SkiaShader.cpp revision d1ad5e62fda248c6d185cde3cb6d9f01a223066c
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" 24d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#include "Layer.h" 25d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#include "Matrix.h" 2606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include "SkiaShader.h" 2706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include "Texture.h" 2806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 2906f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace android { 3006f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace uirenderer { 3106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 3206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Support 3406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 3606f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic const GLint gTileModes[] = { 3706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_CLAMP_TO_EDGE, // == SkShader::kClamp_TileMode 3806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_REPEAT, // == SkShader::kRepeat_Mode 3906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_MIRRORED_REPEAT // == SkShader::kMirror_TileMode 4006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; 4106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 4242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy/** 4342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy * This function does not work for n == 0. 4442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy */ 4542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guystatic inline bool isPowerOfTwo(unsigned int n) { 4642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy return !(n & (n - 1)); 4742e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy} 4842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 4942e1e0d482d774cf18a55773e434f02edb9e4462Romain Guystatic inline void bindUniformColor(int slot, uint32_t color) { 50d679b57ef279239cf11bb6c9bd14fb99b07971c9Romain Guy const float a = ((color >> 24) & 0xff) / 255.0f; 5142e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy glUniform4f(slot, 52d679b57ef279239cf11bb6c9bd14fb99b07971c9Romain Guy a * ((color >> 16) & 0xff) / 255.0f, 53d679b57ef279239cf11bb6c9bd14fb99b07971c9Romain Guy a * ((color >> 8) & 0xff) / 255.0f, 54d679b57ef279239cf11bb6c9bd14fb99b07971c9Romain Guy a * ((color ) & 0xff) / 255.0f, 55d679b57ef279239cf11bb6c9bd14fb99b07971c9Romain Guy a); 5642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy} 5742e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 58d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic inline void bindTexture(Caches* caches, Texture* texture, GLenum wrapS, GLenum wrapT) { 59d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III caches->bindTexture(texture->id); 60d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III texture->setWrapST(wrapS, wrapT); 6124c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy} 6224c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 63d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/** 64d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * Compute the matrix to transform to screen space. 65d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param screenSpace Output param for the computed matrix. 66d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param unitMatrix The unit matrix for gradient shaders, as returned by SkShader::asAGradient, 67d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * or identity. 68d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param localMatrix Local matrix, as returned by SkShader::getLocalMatrix(). 69d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param modelViewMatrix Model view matrix, as supplied by the OpenGLRenderer. 70d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III */ 71d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic void computeScreenSpaceMatrix(mat4& screenSpace, const SkMatrix& unitMatrix, 72d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const SkMatrix& localMatrix, const mat4& modelViewMatrix) { 73d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III mat4 shaderMatrix; 74d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // uses implicit construction 75d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderMatrix.loadInverse(localMatrix); 76d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // again, uses implicit construction 77d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III screenSpace.loadMultiply(unitMatrix, shaderMatrix); 78d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III screenSpace.multiply(modelViewMatrix); 79d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 80d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 81d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III// Returns true if one is a bitmap and the other is a gradient 82d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic bool bitmapAndGradient(SkiaShaderType type1, SkiaShaderType type2) { 83d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return (type1 == kBitmap_SkiaShaderType && type2 == kGradient_SkiaShaderType) 84d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III || (type2 == kBitmap_SkiaShaderType && type1 == kGradient_SkiaShaderType); 85d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 86d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 87d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIISkiaShaderType SkiaShader::getType(const SkShader& shader) { 88d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // First check for a gradient shader. 89d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III switch (shader.asAGradient(NULL)) { 90d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kNone_GradientType: 91d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // Not a gradient shader. Fall through to check for other types. 92d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 93d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kLinear_GradientType: 94d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kRadial_GradientType: 95d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kSweep_GradientType: 96d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kGradient_SkiaShaderType; 97d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III default: 98d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // This is a Skia gradient that has no SkiaShader equivalent. Return None to skip. 99d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kNone_SkiaShaderType; 100d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 1018aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy 102d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // The shader is not a gradient. Check for a bitmap shader. 103d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shader.asABitmap(NULL, NULL, NULL) == SkShader::kDefault_BitmapType) { 104d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kBitmap_SkiaShaderType; 105d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 10606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 107d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // Check for a ComposeShader. 108d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::ComposeRec rec; 109d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shader.asACompose(&rec)) { 110d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const SkiaShaderType shaderAType = getType(*rec.fShaderA); 111d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const SkiaShaderType shaderBType = getType(*rec.fShaderB); 112d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 113d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // Compose is only supported if one is a bitmap and the other is a 114d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // gradient. Otherwise, return None to skip. 115d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!bitmapAndGradient(shaderAType, shaderBType)) { 116d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kNone_SkiaShaderType; 117d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 118d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kCompose_SkiaShaderType; 119d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 12006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 121d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shader.asACustomShader(NULL)) { 122d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kLayer_SkiaShaderType; 123d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 12406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 125d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return kNone_SkiaShaderType; 12606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 12706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 128d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIItypedef void (*describeProc)(Caches* caches, ProgramDescription& description, 129d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, const SkShader& shader); 130d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 131d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIdescribeProc gDescribeProc[] = { 132d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III InvalidSkiaShader::describe, 133d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaBitmapShader::describe, 134d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaGradientShader::describe, 135d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaComposeShader::describe, 136d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaLayerShader::describe, 137d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III}; 138d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 139d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIItypedef void (*setupProgramProc)(Caches* caches, const mat4& modelViewMatrix, 140d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions& extensions, const SkShader& shader); 141d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 142d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIsetupProgramProc gSetupProgramProc[] = { 143d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III InvalidSkiaShader::setupProgram, 144d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaBitmapShader::setupProgram, 145d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaGradientShader::setupProgram, 146d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaComposeShader::setupProgram, 147d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaLayerShader::setupProgram, 148d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III}; 149d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 150d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaShader::describe(Caches* caches, ProgramDescription& description, 151d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, const SkShader& shader) { 152d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gDescribeProc[getType(shader)](caches, description, extensions, shader); 15306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 15406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 155d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, 156d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { 157d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 158d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gSetupProgramProc[getType(shader)](caches, modelViewMatrix, textureUnit, extensions, shader); 15914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 16014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 16106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 1623f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik// Layer shader 1633f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik/////////////////////////////////////////////////////////////////////////////// 1643f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 165d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaLayerShader::describe(Caches*, ProgramDescription& description, 166d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions&, const SkShader& shader) { 1673f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik description.hasBitmap = true; 1683f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik} 1693f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 170d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaLayerShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, 171d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions&, const SkShader& shader) { 172d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Layer* layer; 173d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!shader.asACustomShader(reinterpret_cast<void**>(&layer))) { 174d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("SkiaLayerShader::setupProgram called on the wrong type of shader!"); 175d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 176d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 1773f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik GLuint textureSlot = (*textureUnit)++; 178d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III caches->activeTexture(textureSlot); 1793f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 180d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const float width = layer->getWidth(); 181d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const float height = layer->getHeight(); 1823f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 1833f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik mat4 textureTransform; 184d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III computeScreenSpaceMatrix(textureTransform, SkMatrix::I(), shader.getLocalMatrix(), 185d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III modelViewMatrix); 186d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 1873f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 1883f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik // Uniforms 189d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III layer->bindTexture(); 190d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III layer->setWrap(GL_CLAMP_TO_EDGE); 191d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III layer->setFilter(GL_LINEAR); 1923f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 193d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Program* program = caches->currentProgram; 1943f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik glUniform1i(program->getUniform("bitmapSampler"), textureSlot); 1953f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik glUniformMatrix4fv(program->getUniform("textureTransform"), 1, 1963f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik GL_FALSE, &textureTransform.data[0]); 1973f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik glUniform2f(program->getUniform("textureDimension"), 1.0f / width, 1.0f / height); 1983f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik} 1993f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 2003f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik/////////////////////////////////////////////////////////////////////////////// 20106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Bitmap shader 20206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 20306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 204d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstruct BitmapShaderInfo { 205d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III float width; 206d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III float height; 207d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLenum wrapS; 208d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLenum wrapT; 209d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Texture* texture; 210d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III}; 21124c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 212d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic bool bitmapShaderHelper(Caches* caches, ProgramDescription* description, 213d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III BitmapShaderInfo* shaderInfo, 214d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, 215d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const SkBitmap& bitmap, SkShader::TileMode tileModes[2]) { 216d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Texture* texture = caches->textureCache.get(&bitmap); 217d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!texture) return false; 21806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 21906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float width = texture->width; 22006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float height = texture->height; 221d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLenum wrapS, wrapT; 22206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 223d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (description) { 224d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description->hasBitmap = true; 225d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 22606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // The driver does not support non-power of two mirrored/repeated 22706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // textures, so do it ourselves 22861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy if (!extensions.hasNPot() && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) && 229d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III (tileModes[0] != SkShader::kClamp_TileMode || 230d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III tileModes[1] != SkShader::kClamp_TileMode)) { 231d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (description) { 232d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description->isBitmapNpot = true; 233d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description->bitmapWrapS = gTileModes[tileModes[0]]; 234d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description->bitmapWrapT = gTileModes[tileModes[1]]; 235d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 236d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III wrapS = GL_CLAMP_TO_EDGE; 237d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III wrapT = GL_CLAMP_TO_EDGE; 23829d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy } else { 239d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III wrapS = gTileModes[tileModes[0]]; 240d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III wrapT = gTileModes[tileModes[1]]; 241d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 242d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 243d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shaderInfo) { 244d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderInfo->width = width; 245d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderInfo->height = height; 246d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderInfo->wrapS = wrapS; 247d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderInfo->wrapT = wrapT; 248d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderInfo->texture = texture; 24906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 250d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return true; 25106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 25206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 253d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaBitmapShader::describe(Caches* caches, ProgramDescription& description, 254d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, const SkShader& shader) { 255d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkBitmap bitmap; 256d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::TileMode xy[2]; 257d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shader.asABitmap(&bitmap, NULL, xy) != SkShader::kDefault_BitmapType) { 258d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("SkiaBitmapShader::describe called with a different kind of shader!"); 259d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 260d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III bitmapShaderHelper(caches, &description, NULL, extensions, bitmap, xy); 261d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 262d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 263d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaBitmapShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, 264d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { 265d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkBitmap bitmap; 266d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::TileMode xy[2]; 267d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (shader.asABitmap(&bitmap, NULL, xy) != SkShader::kDefault_BitmapType) { 268d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("SkiaBitmapShader::setupProgram called with a different kind of shader!"); 269d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 270d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 27106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GLuint textureSlot = (*textureUnit)++; 272a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy Caches::getInstance().activeTexture(textureSlot); 2739cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy 274d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III BitmapShaderInfo shaderInfo; 275d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!bitmapShaderHelper(caches, NULL, &shaderInfo, extensions, bitmap, xy)) { 276d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return; 277d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 27806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 279d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Program* program = caches->currentProgram; 280d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Texture* texture = shaderInfo.texture; 281d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 282d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const AutoTexture autoCleanup(texture); 28306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 28406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy mat4 textureTransform; 285d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III computeScreenSpaceMatrix(textureTransform, SkMatrix::I(), shader.getLocalMatrix(), 286d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III modelViewMatrix); 28706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 28806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy // Uniforms 289d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III bindTexture(caches, texture, shaderInfo.wrapS, shaderInfo.wrapT); 290d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy texture->setFilter(GL_LINEAR); 291e3c26851dc315b730ea0fe5ef35bb1db81f6d675Romain Guy 29206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniform1i(program->getUniform("bitmapSampler"), textureSlot); 29306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy glUniformMatrix4fv(program->getUniform("textureTransform"), 1, 29406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_FALSE, &textureTransform.data[0]); 295d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III glUniform2f(program->getUniform("textureDimension"), 1.0f / shaderInfo.width, 296d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 1.0f / shaderInfo.height); 29706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 29806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 29906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 30006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Linear gradient shader 30106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 30206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 303e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guystatic void toUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) { 304e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy SkVector vec = pts[1] - pts[0]; 305e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float mag = vec.length(); 306e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float inv = mag ? 1.0f / mag : 0; 307e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 308e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy vec.scale(inv); 309e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); 310e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postTranslate(-pts[0].fX, -pts[0].fY); 311e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postScale(inv, inv); 312e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy} 313e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 31406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 315ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy// Circular gradient shader 316ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy/////////////////////////////////////////////////////////////////////////////// 317ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 31814830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toCircularUnitMatrix(const float x, const float y, const float radius, 31914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy SkMatrix* matrix) { 32014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy const float inv = 1.0f / radius; 32114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 32214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->postScale(inv, inv); 32314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 32414830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 325ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy/////////////////////////////////////////////////////////////////////////////// 326ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy// Sweep gradient shader 327ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy/////////////////////////////////////////////////////////////////////////////// 328ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 32914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) { 33014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 33114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 33214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 333d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/////////////////////////////////////////////////////////////////////////////// 334d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III// Common gradient code 335d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/////////////////////////////////////////////////////////////////////////////// 33624c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 337d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic bool isSimpleGradient(const SkShader::GradientInfo& gradInfo) { 338d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return gradInfo.fColorCount == 2 && gradInfo.fTileMode == SkShader::kClamp_TileMode; 339d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 340d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 341d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaGradientShader::describe(Caches*, ProgramDescription& description, 342d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, const SkShader& shader) { 343d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::GradientInfo gradInfo; 344d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorCount = 0; 345d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColors = NULL; 346d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorOffsets = NULL; 347d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 348d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III switch (shader.asAGradient(&gradInfo)) { 349d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kLinear_GradientType: 350d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description.gradientType = ProgramDescription::kGradientLinear; 351d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 352d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kRadial_GradientType: 353d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description.gradientType = ProgramDescription::kGradientCircular; 354d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 355d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kSweep_GradientType: 356d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description.gradientType = ProgramDescription::kGradientSweep; 357d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 358d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III default: 359d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // Do nothing. This shader is unsupported. 360d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return; 361d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 362ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy description.hasGradient = true; 363d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description.isSimpleGradient = isSimpleGradient(gradInfo); 364d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 365d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 366d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaGradientShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, 367d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions&, const SkShader& shader) { 368d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // SkShader::GradientInfo.fColorCount is an in/out parameter. As input, it tells asAGradient 369d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // how much space has been allocated for fColors and fColorOffsets. 10 was chosen 370d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // arbitrarily, but should be >= 2. 371d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // As output, it tells the number of actual colors/offsets in the gradient. 372d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const int COLOR_COUNT = 10; 373d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkAutoSTMalloc<COLOR_COUNT, SkColor> colorStorage(COLOR_COUNT); 374d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkAutoSTMalloc<COLOR_COUNT, SkScalar> positionStorage(COLOR_COUNT); 375d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 376d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::GradientInfo gradInfo; 377d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorCount = COLOR_COUNT; 378d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColors = colorStorage.get(); 379d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorOffsets = positionStorage.get(); 380d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 381d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::GradientType gradType = shader.asAGradient(&gradInfo); 382d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 383d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Program* program = caches->currentProgram; 384d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (CC_UNLIKELY(!isSimpleGradient(gradInfo))) { 385d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (gradInfo.fColorCount > COLOR_COUNT) { 386d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // There was not enough room in our arrays for all the colors and offsets. Try again, 387d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // now that we know the true number of colors. 388d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColors = colorStorage.reset(gradInfo.fColorCount); 389d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorOffsets = positionStorage.reset(gradInfo.fColorCount); 390d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 391d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shader.asAGradient(&gradInfo); 392d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 39342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy GLuint textureSlot = (*textureUnit)++; 394d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III caches->activeTexture(textureSlot); 395ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 396d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#ifndef SK_SCALAR_IS_FLOAT 397d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III #error Need to convert gradInfo.fColorOffsets to float! 398d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#endif 399d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III Texture* texture = caches->gradientCache.get(gradInfo.fColors, gradInfo.fColorOffsets, 400d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fColorCount); 40142e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 40242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy // Uniforms 403d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III bindTexture(caches, texture, gTileModes[gradInfo.fTileMode], gTileModes[gradInfo.fTileMode]); 40442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy glUniform1i(program->getUniform("gradientSampler"), textureSlot); 40542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy } else { 406d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III bindUniformColor(program->getUniform("startColor"), gradInfo.fColors[0]); 407d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III bindUniformColor(program->getUniform("endColor"), gradInfo.fColors[1]); 40842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy } 409ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 410d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III caches->dither.setupProgram(program, textureUnit); 411d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 412d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkMatrix unitMatrix; 413d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III switch (gradType) { 414d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kLinear_GradientType: 415d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III toUnitMatrix(gradInfo.fPoint, &unitMatrix); 416d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 417d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kRadial_GradientType: 418d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III toCircularUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, 419d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III gradInfo.fRadius[0], &unitMatrix); 420d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 421d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III case SkShader::kSweep_GradientType: 422d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III toSweepUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, &unitMatrix); 423d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III break; 424d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III default: 425d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("Invalid SkShader gradient type %d", gradType); 426d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 427211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 42814830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy mat4 screenSpace; 429d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III computeScreenSpaceMatrix(screenSpace, unitMatrix, shader.getLocalMatrix(), modelViewMatrix); 430ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); 431ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 432ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 433ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy/////////////////////////////////////////////////////////////////////////////// 43406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Compose shader 43506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 43606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 437d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaComposeShader::describe(Caches* caches, ProgramDescription& description, 438d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const Extensions& extensions, const SkShader& shader) { 439d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::ComposeRec rec; 440d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!shader.asACompose(&rec)) { 441d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("SkiaComposeShader::describe called on the wrong shader type!"); 44243ccf4663c822ddd435b7683cc05221f6169c6c3Romain Guy } 443d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaShader::describe(caches, description, extensions, *rec.fShaderA); 444d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaShader::describe(caches, description, extensions, *rec.fShaderB); 445d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (SkiaShader::getType(*rec.fShaderA) == kBitmap_SkiaShaderType) { 44606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy description.isBitmapFirst = true; 44706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 448d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!SkXfermode::AsMode(rec.fMode, &description.shadersMode)) { 449d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // TODO: Support other modes. 450d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III description.shadersMode = SkXfermode::kSrcOver_Mode; 451d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 45206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 45306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 454d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIvoid SkiaComposeShader::setupProgram(Caches* caches, const mat4& modelViewMatrix, 455d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) { 456d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkShader::ComposeRec rec; 457d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III if (!shader.asACompose(&rec)) { 458d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III LOG_ALWAYS_FATAL("SkiaComposeShader::setupProgram called on the wrong shader type!"); 459d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III } 460d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 461d4289922ce772ed8e170a27d1c9521672b315698Romain Guy // Apply this compose shader's local transform and pass it down to 462d4289922ce772ed8e170a27d1c9521672b315698Romain Guy // the child shaders. They will in turn apply their local transform 463d4289922ce772ed8e170a27d1c9521672b315698Romain Guy // to this matrix. 464d4289922ce772ed8e170a27d1c9521672b315698Romain Guy mat4 transform; 465d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III computeScreenSpaceMatrix(transform, SkMatrix::I(), shader.getLocalMatrix(), 466d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III modelViewMatrix); 467d4289922ce772ed8e170a27d1c9521672b315698Romain Guy 468d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaShader::setupProgram(caches, transform, textureUnit, extensions, *rec.fShaderA); 469d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III SkiaShader::setupProgram(caches, transform, textureUnit, extensions, *rec.fShaderB); 47006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 47106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 47206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace uirenderer 47306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace android 474