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 19922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#include "SkiaShader.h" 2006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 21a1d3c91afbd52c7e8b01f4a9060c5459f02ae7a5Romain Guy#include "Caches.h" 222dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson#include "Extensions.h" 23d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#include "Layer.h" 24d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III#include "Matrix.h" 2506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include "Texture.h" 2606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 27922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#include <SkMatrix.h> 28922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#include <utils/Log.h> 29922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 3006f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace android { 3106f96e2652e4855b6520ad9dd70583677605b79aRomain Guynamespace uirenderer { 3206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 3306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy// Support 3506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 3606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 37922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikstatic const GLenum gTileModes[] = { 3806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_CLAMP_TO_EDGE, // == SkShader::kClamp_TileMode 3906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_REPEAT, // == SkShader::kRepeat_Mode 4006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy GL_MIRRORED_REPEAT // == SkShader::kMirror_TileMode 4106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; 4206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 4342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy/** 4442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy * This function does not work for n == 0. 4542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy */ 4642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guystatic inline bool isPowerOfTwo(unsigned int n) { 4742e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy return !(n & (n - 1)); 4842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy} 4942e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 50922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikstatic inline void bindUniformColor(int slot, FloatColor color) { 51922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform4fv(slot, 1, reinterpret_cast<const float*>(&color)); 52922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 53922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 54d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic inline void bindTexture(Caches* caches, Texture* texture, GLenum wrapS, GLenum wrapT) { 5544eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik caches->textureState().bindTexture(texture->id); 56d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III texture->setWrapST(wrapS, wrapT); 5724c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy} 5824c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 59d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/** 60d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * Compute the matrix to transform to screen space. 61d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param screenSpace Output param for the computed matrix. 62d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param unitMatrix The unit matrix for gradient shaders, as returned by SkShader::asAGradient, 63d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * or identity. 64d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param localMatrix Local matrix, as returned by SkShader::getLocalMatrix(). 65d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III * @param modelViewMatrix Model view matrix, as supplied by the OpenGLRenderer. 66d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III */ 67d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic void computeScreenSpaceMatrix(mat4& screenSpace, const SkMatrix& unitMatrix, 68d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III const SkMatrix& localMatrix, const mat4& modelViewMatrix) { 69d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III mat4 shaderMatrix; 70d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // uses implicit construction 71d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III shaderMatrix.loadInverse(localMatrix); 72d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III // again, uses implicit construction 73d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III screenSpace.loadMultiply(unitMatrix, shaderMatrix); 74d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III screenSpace.multiply(modelViewMatrix); 75d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 76d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 7706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 78828407356dd5c34a3e441604aaf895cbec7c7e66Chris Craik// gradient shader matrix helpers 7906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////// 8006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 81828407356dd5c34a3e441604aaf895cbec7c7e66Chris Craikstatic void toLinearUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) { 82e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy SkVector vec = pts[1] - pts[0]; 83e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float mag = vec.length(); 84e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy const float inv = mag ? 1.0f / mag : 0; 85e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 86e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy vec.scale(inv); 87e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); 88e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postTranslate(-pts[0].fX, -pts[0].fY); 89e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy matrix->postScale(inv, inv); 90e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy} 91e3095e0c1e2a4a4f34f741aa386eae56536ca5aaRomain Guy 9214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toCircularUnitMatrix(const float x, const float y, const float radius, 9314830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy SkMatrix* matrix) { 9414830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy const float inv = 1.0f / radius; 9514830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 9614830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->postScale(inv, inv); 9714830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 9814830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 9914830948d02f768c41b97b7a8d15e1b3cab78267Romain Guystatic void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) { 10014830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy matrix->setTranslate(-x, -y); 10114830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy} 10214830948d02f768c41b97b7a8d15e1b3cab78267Romain Guy 103d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/////////////////////////////////////////////////////////////////////////////// 104d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III// Common gradient code 105d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III/////////////////////////////////////////////////////////////////////////////// 10624c00216687ac87fe531dc4d4168ac0c0ca04ea6Romain Guy 107d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins IIIstatic bool isSimpleGradient(const SkShader::GradientInfo& gradInfo) { 108d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III return gradInfo.fColorCount == 2 && gradInfo.fTileMode == SkShader::kClamp_TileMode; 109d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III} 110d1ad5e62fda248c6d185cde3cb6d9f01a223066cLeon Scroggins III 111922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik/////////////////////////////////////////////////////////////////////////////// 112922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik// Store / apply 113922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik/////////////////////////////////////////////////////////////////////////////// 114922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 115922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreGradient(Caches& caches, const SkShader& shader, const Matrix4 modelViewMatrix, 116922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 117922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData::GradientShaderData* outData) { 118922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkShader::GradientInfo gradInfo; 119922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColorCount = 0; 120922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColors = nullptr; 121922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColorOffsets = nullptr; 122922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 123922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkMatrix unitMatrix; 124922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik switch (shader.asAGradient(&gradInfo)) { 125922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kLinear_GradientType: 126922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->gradientType = ProgramDescription::kGradientLinear; 127922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 128828407356dd5c34a3e441604aaf895cbec7c7e66Chris Craik toLinearUnitMatrix(gradInfo.fPoint, &unitMatrix); 129922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 130922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kRadial_GradientType: 131922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->gradientType = ProgramDescription::kGradientCircular; 132922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 133922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik toCircularUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, 134922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fRadius[0], &unitMatrix); 135922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 136922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kSweep_GradientType: 137922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->gradientType = ProgramDescription::kGradientSweep; 138922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 139922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik toSweepUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, &unitMatrix); 140922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 141922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik default: 142922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // Do nothing. This shader is unsupported. 143922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return false; 144922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 145922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->hasGradient = true; 146922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isSimpleGradient = isSimpleGradient(gradInfo); 147922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 148922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(outData->screenSpace, unitMatrix, 149922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik shader.getLocalMatrix(), modelViewMatrix); 150922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 151922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // re-query shader to get full color / offset data 152922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik std::unique_ptr<SkColor[]> colorStorage(new SkColor[gradInfo.fColorCount]); 153922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik std::unique_ptr<SkScalar[]> colorOffsets(new SkScalar[gradInfo.fColorCount]); 154922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColors = &colorStorage[0]; 155922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColorOffsets = &colorOffsets[0]; 156922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik shader.asAGradient(&gradInfo); 157922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 158922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (CC_UNLIKELY(!isSimpleGradient(gradInfo))) { 159922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientSampler = (*textureUnit)++; 160922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 161922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#ifndef SK_SCALAR_IS_FLOAT 162922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik #error Need to convert gradInfo.fColorOffsets to float! 163922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik#endif 164922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientTexture = caches.gradientCache.get( 165922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik gradInfo.fColors, gradInfo.fColorOffsets, gradInfo.fColorCount); 166922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapST = gTileModes[gradInfo.fTileMode]; 167922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 168922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientSampler = 0; 169922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->gradientTexture = nullptr; 170922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 171922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->startColor.set(gradInfo.fColors[0]); 172922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->endColor.set(gradInfo.fColors[1]); 173922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 174922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 175922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->ditherSampler = (*textureUnit)++; 176922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return true; 177922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 178922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 179922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid applyGradient(Caches& caches, const SkiaShaderData::GradientShaderData& data) { 180922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (CC_UNLIKELY(data.gradientTexture)) { 181922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik caches.textureState().activateTexture(data.gradientSampler); 182922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindTexture(&caches, data.gradientTexture, data.wrapST, data.wrapST); 183922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform1i(caches.program().getUniform("gradientSampler"), data.gradientSampler); 184922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 185922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindUniformColor(caches.program().getUniform("startColor"), data.startColor); 186922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindUniformColor(caches.program().getUniform("endColor"), data.endColor); 187922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 188922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 189922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // TODO: remove sampler slot incrementing from dither.setupProgram, 190922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // since this assignment of slots is done at store, not apply time 191922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint ditherSampler = data.ditherSampler; 192922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik caches.dither.setupProgram(caches.program(), &ditherSampler); 193922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniformMatrix4fv(caches.program().getUniform("screenSpace"), 1, 194922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GL_FALSE, &data.screenSpace.data[0]); 195922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 196922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 197922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreBitmap(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, 198922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 199922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData::BitmapShaderData* outData) { 200922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkBitmap bitmap; 201922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkShader::TileMode xy[2]; 202922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (shader.asABitmap(&bitmap, nullptr, xy) != SkShader::kDefault_BitmapType) { 203922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return false; 204922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 205922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 2066ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik /* 2076ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik * Bypass the AssetAtlas, since those textures: 2086ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik * 1) require UV mapping, which isn't implemented in matrix computation below 2096ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik * 2) can't handle REPEAT simply 2106ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik * 3) are safe to upload here (outside of sync stage), since they're static 2116ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik */ 2126ad690e16f8e139bfd29a035b52ab616d813a74bChris Craik outData->bitmapTexture = caches.textureCache.getAndBypassAtlas(&bitmap); 213922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!outData->bitmapTexture) return false; 214922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 215922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->bitmapSampler = (*textureUnit)++; 216922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 217922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const float width = outData->bitmapTexture->width; 218922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const float height = outData->bitmapTexture->height; 219922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 220922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->hasBitmap = true; 221922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!caches.extensions().hasNPot() 222922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) 223922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik && (xy[0] != SkShader::kClamp_TileMode || xy[1] != SkShader::kClamp_TileMode)) { 224922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isBitmapNpot = true; 225922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->bitmapWrapS = gTileModes[xy[0]]; 226922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->bitmapWrapT = gTileModes[xy[1]]; 227922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 228922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapS = GL_CLAMP_TO_EDGE; 229922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapT = GL_CLAMP_TO_EDGE; 230922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 231922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapS = gTileModes[xy[0]]; 232922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->wrapT = gTileModes[xy[1]]; 233922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 234922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 235922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(outData->textureTransform, SkMatrix::I(), shader.getLocalMatrix(), 236922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik modelViewMatrix); 237922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->textureDimension[0] = 1.0f / width; 238922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik outData->textureDimension[1] = 1.0f / height; 239922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 240922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return true; 241922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 242922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 243922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid applyBitmap(Caches& caches, const SkiaShaderData::BitmapShaderData& data) { 244922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik caches.textureState().activateTexture(data.bitmapSampler); 245922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik bindTexture(&caches, data.bitmapTexture, data.wrapS, data.wrapT); 246922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik data.bitmapTexture->setFilter(GL_LINEAR); 247922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 248922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform1i(caches.program().getUniform("bitmapSampler"), data.bitmapSampler); 249922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniformMatrix4fv(caches.program().getUniform("textureTransform"), 1, GL_FALSE, 250922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik &data.textureTransform.data[0]); 251922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik glUniform2fv(caches.program().getUniform("textureDimension"), 1, &data.textureDimension[0]); 252922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 253922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 254922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris CraikSkiaShaderType getComposeSubType(const SkShader& shader) { 255922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // First check for a gradient shader. 256922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik switch (shader.asAGradient(nullptr)) { 257922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kNone_GradientType: 258922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // Not a gradient shader. Fall through to check for other types. 259922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik break; 260922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kLinear_GradientType: 261922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kRadial_GradientType: 262922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik case SkShader::kSweep_GradientType: 263922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kGradient_SkiaShaderType; 264922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik default: 265922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // This is a Skia gradient that has no SkiaShader equivalent. Return None to skip. 266922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kNone_SkiaShaderType; 267922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 268922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 269922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // The shader is not a gradient. Check for a bitmap shader. 270922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (shader.asABitmap(nullptr, nullptr, nullptr) == SkShader::kDefault_BitmapType) { 271922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kBitmap_SkiaShaderType; 272922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 273922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik return kNone_SkiaShaderType; 274922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 275922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 276922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid storeCompose(Caches& caches, const SkShader& bitmapShader, const SkShader& gradientShader, 277922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const Matrix4& modelViewMatrix, GLuint* textureUnit, 278922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik ProgramDescription* description, SkiaShaderData* outData) { 279922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik LOG_ALWAYS_FATAL_IF(!tryStoreBitmap(caches, bitmapShader, modelViewMatrix, 280922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->bitmapData), 281922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik "failed storing bitmap shader data"); 282922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik LOG_ALWAYS_FATAL_IF(!tryStoreGradient(caches, gradientShader, modelViewMatrix, 283922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik textureUnit, description, &outData->gradientData), 284922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik "failing storing gradient shader data"); 285922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 286922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 287922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikbool tryStoreCompose(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, 288922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik GLuint* textureUnit, ProgramDescription* description, 289922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkiaShaderData* outData) { 290922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 291922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik SkShader::ComposeRec rec; 292922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!shader.asACompose(&rec)) return false; 293922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 294922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const SkiaShaderType shaderAType = getComposeSubType(*rec.fShaderA); 295922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik const SkiaShaderType shaderBType = getComposeSubType(*rec.fShaderB); 296922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 297922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // check that type enum values are the 2 flags that compose the kCompose value 298922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if ((shaderAType & shaderBType) != 0) return false; 299922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if ((shaderAType | shaderBType) != kCompose_SkiaShaderType) return false; 300922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 301922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik mat4 transform; 302922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik computeScreenSpaceMatrix(transform, SkMatrix::I(), shader.getLocalMatrix(), modelViewMatrix); 303922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (shaderAType == kBitmap_SkiaShaderType) { 304922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isBitmapFirst = true; 305922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik storeCompose(caches, *rec.fShaderA, *rec.fShaderB, 306922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik transform, textureUnit, description, outData); 307922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } else { 308922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->isBitmapFirst = false; 309922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik storeCompose(caches, *rec.fShaderB, *rec.fShaderA, 310922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik transform, textureUnit, description, outData); 311922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 312922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!SkXfermode::AsMode(rec.fMode, &description->shadersMode)) { 313922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // TODO: Support other modes. 314922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik description->shadersMode = SkXfermode::kSrcOver_Mode; 315922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 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 386922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craikvoid SkiaShader::apply(Caches& caches, const SkiaShaderData& data) { 387922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (!data.skiaShaderType) return; 388922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 389922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (data.skiaShaderType & kGradient_SkiaShaderType) { 390922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik applyGradient(caches, data.gradientData); 391922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 392922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (data.skiaShaderType & kBitmap_SkiaShaderType) { 393922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik applyBitmap(caches, data.bitmapData); 394922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 395922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 396922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik if (data.skiaShaderType == kLayer_SkiaShaderType) { 397922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik applyLayer(caches, data.layerData); 398922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik } 399922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik} 400922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 40106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace uirenderer 40206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy}; // namespace android 403