SkiaShader.cpp revision a0ed6f03f6f06eb41cbcc15c0a99b4a78fd91bef
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" 24ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv#include "hwui/Bitmap.h" 2506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 26922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#include <SkMatrix.h> 27922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#include <utils/Log.h> 28922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 2906f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace android { 3006f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace uirenderer { 3106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 3206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Support 3406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 36216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craikstatic constexpr GLenum 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 42216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craikstatic_assert(gTileModes[SkShader::kClamp_TileMode] == GL_CLAMP_TO_EDGE, 43216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craik "SkShader TileModes have changed"); 44216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craikstatic_assert(gTileModes[SkShader::kRepeat_TileMode] == GL_REPEAT, 45216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craik "SkShader TileModes have changed"); 46216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craikstatic_assert(gTileModes[SkShader::kMirror_TileMode] == GL_MIRRORED_REPEAT, 47216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craik "SkShader TileModes have changed"); 48216048ffb0a4c41836c6ddb63f9b2e7a64593837Chris Craik 4942e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy/** 5042e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy * This function does not work for n == 0. 5142e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy */ 5242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guystatic inline bool isPowerOfTwo(unsigned int n) { 5342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy return !(n & (n - 1)); 5442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy} 5542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 56922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikstatic inline void bindUniformColor(int slot, FloatColor color) { 57922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform4fv(slot, 1, reinterpret_cast<const float*>(&color)); 58922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 59922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 60d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic inline void bindTexture(Caches* caches, Texture* texture, GLenum wrapS, GLenum wrapT) { 61554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv caches->textureState().bindTexture(texture->target(), texture->id()); 62d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III texture->setWrapST(wrapS, wrapT); 6324c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy} 6424c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 65d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/** 66d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * Compute the matrix to transform to screen space. 67d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param screenSpace Output param for the computed matrix. 68d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param unitMatrix The unit matrix for gradient shaders, as returned by SkShader::asAGradient, 69d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * or identity. 70d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param localMatrix Local matrix, as returned by SkShader::getLocalMatrix(). 71d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param modelViewMatrix Model view matrix, as supplied by the OpenGLRenderer. 72d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III */ 73d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic void computeScreenSpaceMatrix(mat4& screenSpace, const SkMatrix& unitMatrix, 74d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const SkMatrix& localMatrix, const mat4& modelViewMatrix) { 75d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III mat4 shaderMatrix; 76d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // uses implicit construction 77d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderMatrix.loadInverse(localMatrix); 78d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // again, uses implicit construction 79d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III screenSpace.loadMultiply(unitMatrix, shaderMatrix); 80d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III screenSpace.multiply(modelViewMatrix); 81d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 82d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 8306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 84a0ed6f03f6f06eb41cbcc15c0a99b4a78fd91befRomain Guy// Gradient shader matrix helpers 8506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 8606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 87828407356dd5c34a3e441604aaf895cbec7c7e66Chris Craikstatic void toLinearUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) { 88e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy SkVector vec = pts[1] - pts[0]; 89e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float mag = vec.length(); 90e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float inv = mag ? 1.0f / mag : 0; 91e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 92e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy vec.scale(inv); 93e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); 94e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postTranslate(-pts[0].fX, -pts[0].fY); 95e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postScale(inv, inv); 96e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy} 97e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 9814830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toCircularUnitMatrix(const float x, const float y, const float radius, 9914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy SkMatrix* matrix) { 10014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy const float inv = 1.0f / radius; 10114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 10214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->postScale(inv, inv); 10314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 10414830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 10514830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) { 10614830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 10714830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 10814830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 109d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/////////////////////////////////////////////////////////////////////////////// 110d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III// Common gradient code 111d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/////////////////////////////////////////////////////////////////////////////// 11224c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 113d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic bool isSimpleGradient(const SkShader::GradientInfo& gradInfo) { 114d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return gradInfo.fColorCount == 2 && gradInfo.fTileMode == SkShader::kClamp_TileMode; 115d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 116d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 117922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik/////////////////////////////////////////////////////////////////////////////// 118922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik// Store / apply 119922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik/////////////////////////////////////////////////////////////////////////////// 120922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 121922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreGradient(Caches& caches, const SkShader& shader, const Matrix4 modelViewMatrix, 122922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 123922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData::GradientShaderData* outData) { 124922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkShader::GradientInfo gradInfo; 125922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColorCount = 0; 126922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColors = nullptr; 127922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColorOffsets = nullptr; 128922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 129922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkMatrix unitMatrix; 130922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik switch (shader.asAGradient(&gradInfo)) { 131922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kLinear_GradientType: 132922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->gradientType = ProgramDescription::kGradientLinear; 133922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 134828407356dd5c34a3e441604aaf895cbec7c7e66Chris Craik toLinearUnitMatrix(gradInfo.fPoint, &unitMatrix); 135922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 136922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kRadial_GradientType: 137922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->gradientType = ProgramDescription::kGradientCircular; 138922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 139922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik toCircularUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, 140922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fRadius[0], &unitMatrix); 141922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 142922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kSweep_GradientType: 143922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->gradientType = ProgramDescription::kGradientSweep; 144922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 145922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik toSweepUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, &unitMatrix); 146922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 147922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik default: 148922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // Do nothing. This shader is unsupported. 149922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return false; 150922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 151922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->hasGradient = true; 152922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isSimpleGradient = isSimpleGradient(gradInfo); 153922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 154922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(outData->screenSpace, unitMatrix, 155922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik shader.getLocalMatrix(), modelViewMatrix); 156922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 157922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // re-query shader to get full color / offset data 158922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik std::unique_ptr<SkColor[]> colorStorage(new SkColor[gradInfo.fColorCount]); 159922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik std::unique_ptr<SkScalar[]> colorOffsets(new SkScalar[gradInfo.fColorCount]); 160922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColors = &colorStorage[0]; 161922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColorOffsets = &colorOffsets[0]; 162922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik shader.asAGradient(&gradInfo); 163922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 164a0ed6f03f6f06eb41cbcc15c0a99b4a78fd91befRomain Guy if (CC_UNLIKELY(!description->isSimpleGradient)) { 165922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientSampler = (*textureUnit)++; 166922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 167922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#ifndef SK_SCALAR_IS_FLOAT 168922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik #error Need to convert gradInfo.fColorOffsets to float! 169922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#endif 170922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientTexture = caches.gradientCache.get( 171922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColors, gradInfo.fColorOffsets, gradInfo.fColorCount); 172922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapST = gTileModes[gradInfo.fTileMode]; 173922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 174922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientSampler = 0; 175922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientTexture = nullptr; 176922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 177a0ed6f03f6f06eb41cbcc15c0a99b4a78fd91befRomain Guy outData->startColor.setUnPreMultipliedSRGB(gradInfo.fColors[0]); 178a0ed6f03f6f06eb41cbcc15c0a99b4a78fd91befRomain Guy outData->endColor.setUnPreMultipliedSRGB(gradInfo.fColors[1]); 179922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 180922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 181922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return true; 182922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 183922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 184253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guyvoid applyGradient(Caches& caches, const SkiaShaderData::GradientShaderData& data, 185253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy const GLsizei width, const GLsizei height) { 186253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy 187922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (CC_UNLIKELY(data.gradientTexture)) { 188922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik caches.textureState().activateTexture(data.gradientSampler); 189922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindTexture(&caches, data.gradientTexture, data.wrapST, data.wrapST); 190922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform1i(caches.program().getUniform("gradientSampler"), data.gradientSampler); 191922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 192922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindUniformColor(caches.program().getUniform("startColor"), data.startColor); 193922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindUniformColor(caches.program().getUniform("endColor"), data.endColor); 194922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 195922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 196253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy glUniform2f(caches.program().getUniform("screenSize"), 1.0f / width, 1.0f / height); 197922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniformMatrix4fv(caches.program().getUniform("screenSpace"), 1, 198922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GL_FALSE, &data.screenSpace.data[0]); 199922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 200922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 201922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreBitmap(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, 202922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 203922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData::BitmapShaderData* outData) { 204922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkBitmap bitmap; 205922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkShader::TileMode xy[2]; 206f35b989d26bb98900f6c5fa2e586326b30b6e161Leon Scroggins III if (!shader.isABitmap(&bitmap, nullptr, xy)) { 207922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return false; 208922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 209922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 210ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv // TODO: create hwui-owned BitmapShader. 211ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv Bitmap* hwuiBitmap = static_cast<Bitmap*>(bitmap.pixelRef()); 212ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv outData->bitmapTexture = caches.textureCache.get(hwuiBitmap); 213922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!outData->bitmapTexture) return false; 214922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 215922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->bitmapSampler = (*textureUnit)++; 216922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 21738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck const float width = outData->bitmapTexture->width(); 21838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck const float height = outData->bitmapTexture->height(); 219922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 220922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->hasBitmap = true; 221554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv // gralloc doesn't support non-clamp modes 222554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv if (hwuiBitmap->isHardware() || (!caches.extensions().hasNPot() 223922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) 224554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv && (xy[0] != SkShader::kClamp_TileMode || xy[1] != SkShader::kClamp_TileMode))) { 225554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv // need non-clamp mode, but it's not supported for this draw, 226554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv // so enable custom shader logic to mimic 227554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv description->useShaderBasedWrap = true; 228922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->bitmapWrapS = gTileModes[xy[0]]; 229922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->bitmapWrapT = gTileModes[xy[1]]; 230922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 231922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapS = GL_CLAMP_TO_EDGE; 232922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapT = GL_CLAMP_TO_EDGE; 233922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 234922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapS = gTileModes[xy[0]]; 235922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapT = gTileModes[xy[1]]; 236922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 237922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 238922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(outData->textureTransform, SkMatrix::I(), shader.getLocalMatrix(), 239922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik modelViewMatrix); 240922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->textureDimension[0] = 1.0f / width; 241922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->textureDimension[1] = 1.0f / height; 242922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 243922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return true; 244922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 245922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 246922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid applyBitmap(Caches& caches, const SkiaShaderData::BitmapShaderData& data) { 247922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik caches.textureState().activateTexture(data.bitmapSampler); 248922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindTexture(&caches, data.bitmapTexture, data.wrapS, data.wrapT); 249922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik data.bitmapTexture->setFilter(GL_LINEAR); 250922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 251922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform1i(caches.program().getUniform("bitmapSampler"), data.bitmapSampler); 252922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniformMatrix4fv(caches.program().getUniform("textureTransform"), 1, GL_FALSE, 253922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik &data.textureTransform.data[0]); 254922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform2fv(caches.program().getUniform("textureDimension"), 1, &data.textureDimension[0]); 255922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 256922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 257922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris CraikSkiaShaderType getComposeSubType(const SkShader& shader) { 258922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // First check for a gradient shader. 259922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik switch (shader.asAGradient(nullptr)) { 260922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kNone_GradientType: 261922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // Not a gradient shader. Fall through to check for other types. 262922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 263922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kLinear_GradientType: 264922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kRadial_GradientType: 265922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kSweep_GradientType: 266922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kGradient_SkiaShaderType; 267922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik default: 268922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // This is a Skia gradient that has no SkiaShader equivalent. Return None to skip. 269922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kNone_SkiaShaderType; 270922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 271922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 272922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // The shader is not a gradient. Check for a bitmap shader. 273f35b989d26bb98900f6c5fa2e586326b30b6e161Leon Scroggins III if (shader.isABitmap()) { 274922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kBitmap_SkiaShaderType; 275922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 276922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kNone_SkiaShaderType; 277922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 278922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 279922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid storeCompose(Caches& caches, const SkShader& bitmapShader, const SkShader& gradientShader, 280922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const Matrix4& modelViewMatrix, GLuint* textureUnit, 281922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik ProgramDescription* description, SkiaShaderData* outData) { 282922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik LOG_ALWAYS_FATAL_IF(!tryStoreBitmap(caches, bitmapShader, modelViewMatrix, 283922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->bitmapData), 284922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik "failed storing bitmap shader data"); 285922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik LOG_ALWAYS_FATAL_IF(!tryStoreGradient(caches, gradientShader, modelViewMatrix, 286922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->gradientData), 287922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik "failing storing gradient shader data"); 288922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 289922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 290922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreCompose(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, 291922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 292922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData* outData) { 293922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 294922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkShader::ComposeRec rec; 295922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!shader.asACompose(&rec)) return false; 296922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 297922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const SkiaShaderType shaderAType = getComposeSubType(*rec.fShaderA); 298922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const SkiaShaderType shaderBType = getComposeSubType(*rec.fShaderB); 299922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 300922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // check that type enum values are the 2 flags that compose the kCompose value 301922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if ((shaderAType & shaderBType) != 0) return false; 302922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if ((shaderAType | shaderBType) != kCompose_SkiaShaderType) return false; 303922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 304922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik mat4 transform; 305922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(transform, SkMatrix::I(), shader.getLocalMatrix(), modelViewMatrix); 306922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (shaderAType == kBitmap_SkiaShaderType) { 307922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isBitmapFirst = true; 308922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik storeCompose(caches, *rec.fShaderA, *rec.fShaderB, 309922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik transform, textureUnit, description, outData); 310922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 311922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isBitmapFirst = false; 312922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik storeCompose(caches, *rec.fShaderB, *rec.fShaderA, 313922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik transform, textureUnit, description, outData); 314922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 315c2f31df8b3b9a237e9abffc59c61804ad8495073Mike Reed description->shadersMode = rec.fBlendMode; 316922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return true; 317922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 318922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 319922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreLayer(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, 320922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 321922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData::LayerShaderData* outData) { 322922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik Layer* layer; 323922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!shader.asACustomShader(reinterpret_cast<void**>(&layer))) { 324922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return false; 325922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 326922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 327922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->hasBitmap = true; 32836a35e366a65980843b96759f863643f17ca1ee7Chris Craik outData->layer = layer; 329922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->bitmapSampler = (*textureUnit)++; 330922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 331922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const float width = layer->getWidth(); 332922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const float height = layer->getHeight(); 333922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 334922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(outData->textureTransform, SkMatrix::I(), shader.getLocalMatrix(), 335922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik modelViewMatrix); 336922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 337922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->textureDimension[0] = 1.0f / width; 338922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->textureDimension[1] = 1.0f / height; 339922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return true; 340922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 341922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 342922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid applyLayer(Caches& caches, const SkiaShaderData::LayerShaderData& data) { 343922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik caches.textureState().activateTexture(data.bitmapSampler); 344922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 345922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik data.layer->bindTexture(); 346922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik data.layer->setWrap(GL_CLAMP_TO_EDGE); 347922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik data.layer->setFilter(GL_LINEAR); 348922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 349922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform1i(caches.program().getUniform("bitmapSampler"), data.bitmapSampler); 350922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniformMatrix4fv(caches.program().getUniform("textureTransform"), 1, 351922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GL_FALSE, &data.textureTransform.data[0]); 352922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform2fv(caches.program().getUniform("textureDimension"), 1, &data.textureDimension[0]); 353922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 354922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 35553e51e4aa933f9603587e1780f446c18816bf9beChris Craikvoid SkiaShader::store(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, 356922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 357922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData* outData) { 35853e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (tryStoreGradient(caches, shader, modelViewMatrix, 359922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->gradientData)) { 360922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->skiaShaderType = kGradient_SkiaShaderType; 361922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return; 362922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 363922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 36453e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (tryStoreBitmap(caches, shader, modelViewMatrix, 365922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->bitmapData)) { 366922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->skiaShaderType = kBitmap_SkiaShaderType; 367922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return; 368922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 369922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 37053e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (tryStoreCompose(caches, shader, modelViewMatrix, 371922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, outData)) { 372922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->skiaShaderType = kCompose_SkiaShaderType; 373922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return; 374922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 375922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 37653e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (tryStoreLayer(caches, shader, modelViewMatrix, 377922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->layerData)) { 378922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->skiaShaderType = kLayer_SkiaShaderType; 379e310f83d591dc3fb7bd5c684239481a586f00662Chris Craik return; 380922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 381e310f83d591dc3fb7bd5c684239481a586f00662Chris Craik 382e310f83d591dc3fb7bd5c684239481a586f00662Chris Craik // Unknown/unsupported type, so explicitly ignore shader 383e310f83d591dc3fb7bd5c684239481a586f00662Chris Craik outData->skiaShaderType = kNone_SkiaShaderType; 384922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 385922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 386253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guyvoid SkiaShader::apply(Caches& caches, const SkiaShaderData& data, 387253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy const GLsizei width, const GLsizei height) { 388922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!data.skiaShaderType) return; 389922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 390922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (data.skiaShaderType & kGradient_SkiaShaderType) { 391253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy applyGradient(caches, data.gradientData, width, height); 392922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 393922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (data.skiaShaderType & kBitmap_SkiaShaderType) { 394922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik applyBitmap(caches, data.bitmapData); 395922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 396922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 397922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (data.skiaShaderType == kLayer_SkiaShaderType) { 398922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik applyLayer(caches, data.layerData); 399922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 400922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 401922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 40206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace uirenderer 40306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace android 404