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 17922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#include "SkiaShader.h" 1806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 19a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy#include "Caches.h" 202dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson#include "Extensions.h" 21d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#include "Layer.h" 22d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#include "Matrix.h" 2306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include "Texture.h" 2406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 25922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#include <SkMatrix.h> 26922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#include <utils/Log.h> 27922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 2806f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace android { 2906f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace uirenderer { 3006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 3106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Support 3306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 35216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craikstatic constexpr GLenum gTileModes[] = { 3606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_CLAMP_TO_EDGE, // == SkShader::kClamp_TileMode 3706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_REPEAT, // == SkShader::kRepeat_Mode 3806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_MIRRORED_REPEAT // == SkShader::kMirror_TileMode 3906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; 4006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 41216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craikstatic_assert(gTileModes[SkShader::kClamp_TileMode] == GL_CLAMP_TO_EDGE, 42216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craik "SkShader TileModes have changed"); 43216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craikstatic_assert(gTileModes[SkShader::kRepeat_TileMode] == GL_REPEAT, 44216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craik "SkShader TileModes have changed"); 45216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craikstatic_assert(gTileModes[SkShader::kMirror_TileMode] == GL_MIRRORED_REPEAT, 46216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craik "SkShader TileModes have changed"); 47216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craik 4842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy/** 4942e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy * This function does not work for n == 0. 5042e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy */ 5142e1e0d482d774cf18a55773e434f02edb9e4462Romain Guystatic inline bool isPowerOfTwo(unsigned int n) { 5242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy return !(n & (n - 1)); 5342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy} 5442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 55922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikstatic inline void bindUniformColor(int slot, FloatColor color) { 56922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform4fv(slot, 1, reinterpret_cast<const float*>(&color)); 57922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 58922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 59d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic inline void bindTexture(Caches* caches, Texture* texture, GLenum wrapS, GLenum wrapT) { 6038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck caches->textureState().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 8206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 83828407356dd5c34a3e441604aaf895cbec7c7e66Chris Craik// gradient shader matrix helpers 8406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 8506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 86828407356dd5c34a3e441604aaf895cbec7c7e66Chris Craikstatic void toLinearUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) { 87e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy SkVector vec = pts[1] - pts[0]; 88e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float mag = vec.length(); 89e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float inv = mag ? 1.0f / mag : 0; 90e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 91e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy vec.scale(inv); 92e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); 93e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postTranslate(-pts[0].fX, -pts[0].fY); 94e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postScale(inv, inv); 95e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy} 96e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 9714830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toCircularUnitMatrix(const float x, const float y, const float radius, 9814830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy SkMatrix* matrix) { 9914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy const float inv = 1.0f / radius; 10014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 10114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->postScale(inv, inv); 10214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 10314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 10414830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) { 10514830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 10614830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 10714830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 108d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/////////////////////////////////////////////////////////////////////////////// 109d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III// Common gradient code 110d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/////////////////////////////////////////////////////////////////////////////// 11124c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 112d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic bool isSimpleGradient(const SkShader::GradientInfo& gradInfo) { 113d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return gradInfo.fColorCount == 2 && gradInfo.fTileMode == SkShader::kClamp_TileMode; 114d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 115d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 116922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik/////////////////////////////////////////////////////////////////////////////// 117922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik// Store / apply 118922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik/////////////////////////////////////////////////////////////////////////////// 119922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 120922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreGradient(Caches& caches, const SkShader& shader, const Matrix4 modelViewMatrix, 121922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 122922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData::GradientShaderData* outData) { 123922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkShader::GradientInfo gradInfo; 124922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColorCount = 0; 125922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColors = nullptr; 126922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColorOffsets = nullptr; 127922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 128922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkMatrix unitMatrix; 129922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik switch (shader.asAGradient(&gradInfo)) { 130922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kLinear_GradientType: 131922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->gradientType = ProgramDescription::kGradientLinear; 132922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 133828407356dd5c34a3e441604aaf895cbec7c7e66Chris Craik toLinearUnitMatrix(gradInfo.fPoint, &unitMatrix); 134922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 135922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kRadial_GradientType: 136922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->gradientType = ProgramDescription::kGradientCircular; 137922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 138922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik toCircularUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, 139922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fRadius[0], &unitMatrix); 140922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 141922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kSweep_GradientType: 142922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->gradientType = ProgramDescription::kGradientSweep; 143922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 144922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik toSweepUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, &unitMatrix); 145922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 146922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik default: 147922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // Do nothing. This shader is unsupported. 148922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return false; 149922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 150922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->hasGradient = true; 151922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isSimpleGradient = isSimpleGradient(gradInfo); 152922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 153922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(outData->screenSpace, unitMatrix, 154922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik shader.getLocalMatrix(), modelViewMatrix); 155922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 156922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // re-query shader to get full color / offset data 157922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik std::unique_ptr<SkColor[]> colorStorage(new SkColor[gradInfo.fColorCount]); 158922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik std::unique_ptr<SkScalar[]> colorOffsets(new SkScalar[gradInfo.fColorCount]); 159922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColors = &colorStorage[0]; 160922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColorOffsets = &colorOffsets[0]; 161922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik shader.asAGradient(&gradInfo); 162922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 163922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (CC_UNLIKELY(!isSimpleGradient(gradInfo))) { 164922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientSampler = (*textureUnit)++; 165922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 166922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#ifndef SK_SCALAR_IS_FLOAT 167922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik #error Need to convert gradInfo.fColorOffsets to float! 168922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#endif 169922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientTexture = caches.gradientCache.get( 170922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColors, gradInfo.fColorOffsets, gradInfo.fColorCount); 171922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapST = gTileModes[gradInfo.fTileMode]; 172922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 173922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientSampler = 0; 174922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientTexture = nullptr; 175922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 176922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->startColor.set(gradInfo.fColors[0]); 177922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->endColor.set(gradInfo.fColors[1]); 178922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 179922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 180922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->ditherSampler = (*textureUnit)++; 181922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return true; 182922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 183922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 184922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid applyGradient(Caches& caches, const SkiaShaderData::GradientShaderData& data) { 185922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (CC_UNLIKELY(data.gradientTexture)) { 186922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik caches.textureState().activateTexture(data.gradientSampler); 187922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindTexture(&caches, data.gradientTexture, data.wrapST, data.wrapST); 188922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform1i(caches.program().getUniform("gradientSampler"), data.gradientSampler); 189922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 190922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindUniformColor(caches.program().getUniform("startColor"), data.startColor); 191922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindUniformColor(caches.program().getUniform("endColor"), data.endColor); 192922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 193922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 194922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // TODO: remove sampler slot incrementing from dither.setupProgram, 195922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // since this assignment of slots is done at store, not apply time 196922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint ditherSampler = data.ditherSampler; 197922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik caches.dither.setupProgram(caches.program(), &ditherSampler); 198922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniformMatrix4fv(caches.program().getUniform("screenSpace"), 1, 199922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GL_FALSE, &data.screenSpace.data[0]); 200922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 201922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 202922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreBitmap(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, 203922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 204922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData::BitmapShaderData* outData) { 205922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkBitmap bitmap; 206922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkShader::TileMode xy[2]; 207f35b989d26bb98900f6c5fa2e586326b30b6e161Leon Scroggins III if (!shader.isABitmap(&bitmap, nullptr, xy)) { 208922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return false; 209922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 210922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 2116ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik /* 2126ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik * Bypass the AssetAtlas, since those textures: 2136ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik * 1) require UV mapping, which isn't implemented in matrix computation below 2146ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik * 2) can't handle REPEAT simply 2156ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik * 3) are safe to upload here (outside of sync stage), since they're static 2166ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik */ 2176ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik outData->bitmapTexture = caches.textureCache.getAndBypassAtlas(&bitmap); 218922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!outData->bitmapTexture) return false; 219922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 220922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->bitmapSampler = (*textureUnit)++; 221922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 22238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck const float width = outData->bitmapTexture->width(); 22338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck const float height = outData->bitmapTexture->height(); 224922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 225922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->hasBitmap = true; 226922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!caches.extensions().hasNPot() 227922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) 228922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik && (xy[0] != SkShader::kClamp_TileMode || xy[1] != SkShader::kClamp_TileMode)) { 229922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isBitmapNpot = true; 230922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->bitmapWrapS = gTileModes[xy[0]]; 231922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->bitmapWrapT = gTileModes[xy[1]]; 232922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 233922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapS = GL_CLAMP_TO_EDGE; 234922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapT = GL_CLAMP_TO_EDGE; 235922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 236922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapS = gTileModes[xy[0]]; 237922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapT = gTileModes[xy[1]]; 238922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 239922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 240922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(outData->textureTransform, SkMatrix::I(), shader.getLocalMatrix(), 241922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik modelViewMatrix); 242922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->textureDimension[0] = 1.0f / width; 243922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->textureDimension[1] = 1.0f / height; 244922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 245922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return true; 246922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 247922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 248922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid applyBitmap(Caches& caches, const SkiaShaderData::BitmapShaderData& data) { 249922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik caches.textureState().activateTexture(data.bitmapSampler); 250922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindTexture(&caches, data.bitmapTexture, data.wrapS, data.wrapT); 251922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik data.bitmapTexture->setFilter(GL_LINEAR); 252922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 253922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform1i(caches.program().getUniform("bitmapSampler"), data.bitmapSampler); 254922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniformMatrix4fv(caches.program().getUniform("textureTransform"), 1, GL_FALSE, 255922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik &data.textureTransform.data[0]); 256922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform2fv(caches.program().getUniform("textureDimension"), 1, &data.textureDimension[0]); 257922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 258922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 259922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris CraikSkiaShaderType getComposeSubType(const SkShader& shader) { 260922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // First check for a gradient shader. 261922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik switch (shader.asAGradient(nullptr)) { 262922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kNone_GradientType: 263922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // Not a gradient shader. Fall through to check for other types. 264922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 265922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kLinear_GradientType: 266922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kRadial_GradientType: 267922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kSweep_GradientType: 268922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kGradient_SkiaShaderType; 269922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik default: 270922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // This is a Skia gradient that has no SkiaShader equivalent. Return None to skip. 271922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kNone_SkiaShaderType; 272922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 273922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 274922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // The shader is not a gradient. Check for a bitmap shader. 275f35b989d26bb98900f6c5fa2e586326b30b6e161Leon Scroggins III if (shader.isABitmap()) { 276922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kBitmap_SkiaShaderType; 277922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 278922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kNone_SkiaShaderType; 279922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 280922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 281922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid storeCompose(Caches& caches, const SkShader& bitmapShader, const SkShader& gradientShader, 282922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const Matrix4& modelViewMatrix, GLuint* textureUnit, 283922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik ProgramDescription* description, SkiaShaderData* outData) { 284922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik LOG_ALWAYS_FATAL_IF(!tryStoreBitmap(caches, bitmapShader, modelViewMatrix, 285922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->bitmapData), 286922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik "failed storing bitmap shader data"); 287922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik LOG_ALWAYS_FATAL_IF(!tryStoreGradient(caches, gradientShader, modelViewMatrix, 288922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->gradientData), 289922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik "failing storing gradient shader data"); 290922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 291922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 292922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreCompose(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, 293922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 294922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData* outData) { 295922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 296922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkShader::ComposeRec rec; 297922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!shader.asACompose(&rec)) return false; 298922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 299922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const SkiaShaderType shaderAType = getComposeSubType(*rec.fShaderA); 300922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const SkiaShaderType shaderBType = getComposeSubType(*rec.fShaderB); 301922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 302922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // check that type enum values are the 2 flags that compose the kCompose value 303922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if ((shaderAType & shaderBType) != 0) return false; 304922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if ((shaderAType | shaderBType) != kCompose_SkiaShaderType) return false; 305922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 306922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik mat4 transform; 307922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(transform, SkMatrix::I(), shader.getLocalMatrix(), modelViewMatrix); 308922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (shaderAType == kBitmap_SkiaShaderType) { 309922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isBitmapFirst = true; 310922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik storeCompose(caches, *rec.fShaderA, *rec.fShaderB, 311922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik transform, textureUnit, description, outData); 312922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 313922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isBitmapFirst = false; 314922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik storeCompose(caches, *rec.fShaderB, *rec.fShaderA, 315922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik transform, textureUnit, description, outData); 316922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 317922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!SkXfermode::AsMode(rec.fMode, &description->shadersMode)) { 318922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // TODO: Support other modes. 319922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->shadersMode = SkXfermode::kSrcOver_Mode; 320922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 321922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return true; 322922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 323922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 324922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreLayer(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, 325922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 326922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData::LayerShaderData* outData) { 327922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik Layer* layer; 328922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!shader.asACustomShader(reinterpret_cast<void**>(&layer))) { 329922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return false; 330922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 331922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 332922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->hasBitmap = true; 33336a35e366a65980843b96759f863643f17ca1ee7Chris Craik outData->layer = layer; 334922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->bitmapSampler = (*textureUnit)++; 335922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 336922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const float width = layer->getWidth(); 337922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const float height = layer->getHeight(); 338922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 339922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(outData->textureTransform, SkMatrix::I(), shader.getLocalMatrix(), 340922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik modelViewMatrix); 341922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 342922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->textureDimension[0] = 1.0f / width; 343922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->textureDimension[1] = 1.0f / height; 344922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return true; 345922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 346922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 347922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid applyLayer(Caches& caches, const SkiaShaderData::LayerShaderData& data) { 348922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik caches.textureState().activateTexture(data.bitmapSampler); 349922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 350922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik data.layer->bindTexture(); 351922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik data.layer->setWrap(GL_CLAMP_TO_EDGE); 352922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik data.layer->setFilter(GL_LINEAR); 353922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 354922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform1i(caches.program().getUniform("bitmapSampler"), data.bitmapSampler); 355922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniformMatrix4fv(caches.program().getUniform("textureTransform"), 1, 356922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GL_FALSE, &data.textureTransform.data[0]); 357922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform2fv(caches.program().getUniform("textureDimension"), 1, &data.textureDimension[0]); 358922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 359922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 36053e51e4aa933f9603587e1780f446c18816bf9beChris Craikvoid SkiaShader::store(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, 361922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 362922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData* outData) { 36353e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (tryStoreGradient(caches, shader, modelViewMatrix, 364922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->gradientData)) { 365922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->skiaShaderType = kGradient_SkiaShaderType; 366922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return; 367922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 368922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 36953e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (tryStoreBitmap(caches, shader, modelViewMatrix, 370922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->bitmapData)) { 371922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->skiaShaderType = kBitmap_SkiaShaderType; 372922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return; 373922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 374922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 37553e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (tryStoreCompose(caches, shader, modelViewMatrix, 376922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, outData)) { 377922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->skiaShaderType = kCompose_SkiaShaderType; 378922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return; 379922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 380922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 38153e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (tryStoreLayer(caches, shader, modelViewMatrix, 382922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->layerData)) { 383922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->skiaShaderType = kLayer_SkiaShaderType; 384e310f83d591dc3fb7bd5c684239481a586f00662Chris Craik return; 385922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 386e310f83d591dc3fb7bd5c684239481a586f00662Chris Craik 387e310f83d591dc3fb7bd5c684239481a586f00662Chris Craik // Unknown/unsupported type, so explicitly ignore shader 388e310f83d591dc3fb7bd5c684239481a586f00662Chris Craik outData->skiaShaderType = kNone_SkiaShaderType; 389922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 390922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 391922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid SkiaShader::apply(Caches& caches, const SkiaShaderData& data) { 392922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!data.skiaShaderType) return; 393922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 394922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (data.skiaShaderType & kGradient_SkiaShaderType) { 395922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik applyGradient(caches, data.gradientData); 396922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 397922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (data.skiaShaderType & kBitmap_SkiaShaderType) { 398922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik applyBitmap(caches, data.bitmapData); 399922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 400922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 401922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (data.skiaShaderType == kLayer_SkiaShaderType) { 402922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik applyLayer(caches, data.layerData); 403922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 404922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 405922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 40606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace uirenderer 40706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace android 408