1f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org/* 2f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org * Copyright 2012 The Android Open Source Project 3f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org * 4f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be 5f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org * found in the LICENSE file. 6f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org */ 7f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 8f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org#include "SkLightingImageFilter.h" 9f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org#include "SkBitmap.h" 10a4083c97d48e8a4f88e2797d7363f141e3d42553Cary Clark#include "SkColorData.h" 1162745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett#include "SkColorSpaceXformer.h" 1260aaeb2b551d5e3e90baacac315e899e26f758f1Cary Clark#include "SkImageFilterPriv.h" 133d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips#include "SkPoint3.h" 148b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 15ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips#include "SkSpecialImage.h" 16300f562dedd02df2f41de443c8b58ab2ceaed0f0tomhudson@google.com#include "SkTypes.h" 173d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips#include "SkWriteBuffer.h" 18cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 19cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 20cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen#include "GrContext.h" 2102fa32c6d1ef4b7b05aa06df8be4add42a1712d3csmartdalton#include "GrFixedClip.h" 22eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "GrFragmentProcessor.h" 23cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen#include "GrPaint.h" 247f6cd90f0c8f6e8dd658cb1b1c587b833adfc364Robert Phillips#include "GrRenderTargetContext.h" 25646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips#include "GrTexture.h" 267f6cd90f0c8f6e8dd658cb1b1c587b833adfc364Robert Phillips#include "GrTextureProxy.h" 277f6cd90f0c8f6e8dd658cb1b1c587b833adfc364Robert Phillips 281de87df0b743e30619b8ba93ab0169fd41d0feaerobertphillips#include "SkGr.h" 299bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco#include "effects/GrTextureDomain.h" 3064c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLFragmentProcessor.h" 312d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h" 32018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h" 337ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h" 3494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#include "../private/GrGLSL.h" 35894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 36894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgclass GrGLDiffuseLightingEffect; 37894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgclass GrGLSpecularLightingEffect; 38f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 39dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com// For brevity 40018fb62d12d1febf121fe265da5b6117b86a6541egdanieltypedef GrGLSLProgramDataManager::UniformHandle UniformHandle; 41cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 42032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com 4380ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breedconst SkScalar gOneThird = SkIntToScalar(1) / 3; 4480ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breedconst SkScalar gTwoThirds = SkIntToScalar(2) / 3; 454b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.orgconst SkScalar gOneHalf = 0.5f; 464b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.orgconst SkScalar gOneQuarter = 0.25f; 47f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 48cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 4962745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic void setUniformPoint3(const GrGLSLProgramDataManager& pdman, UniformHandle uni, 5062745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett const SkPoint3& point) { 51018fb62d12d1febf121fe265da5b6117b86a6541egdaniel GR_STATIC_ASSERT(sizeof(SkPoint3) == 3 * sizeof(float)); 527510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set3fv(uni, 1, &point.fX); 53894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 54894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 5562745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic void setUniformNormal3(const GrGLSLProgramDataManager& pdman, UniformHandle uni, 5662745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett const SkPoint3& point) { 573d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips setUniformPoint3(pdman, uni, point); 58f4770d7e841a34d74d7f76a33312f4c5624da831senorblanco@chromium.org} 59cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 60f4770d7e841a34d74d7f76a33312f4c5624da831senorblanco@chromium.org 61f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org// Shift matrix components to the left, as we advance pixels to the right. 6262745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline void shiftMatrixLeft(int m[9]) { 63f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org m[0] = m[1]; 64f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org m[3] = m[4]; 65f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org m[6] = m[7]; 66f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org m[1] = m[2]; 67f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org m[4] = m[5]; 68f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org m[7] = m[8]; 69f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 70f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 71992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverthstatic inline void fast_normalize(SkPoint3* vector) { 72992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth // add a tiny bit so we don't have to worry about divide-by-zero 73992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth SkScalar magSq = vector->dot(*vector) + SK_ScalarNearlyZero; 74992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth SkScalar scale = sk_float_rsqrt(magSq); 75992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth vector->fX *= scale; 76992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth vector->fY *= scale; 77992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth vector->fZ *= scale; 78992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth} 79992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth 80959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillipsstatic SkPoint3 read_point3(SkReadBuffer& buffer) { 810c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkPoint3 point; 820c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed point.fX = buffer.readScalar(); 830c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed point.fY = buffer.readScalar(); 840c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed point.fZ = buffer.readScalar(); 850c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed buffer.validate(SkScalarIsFinite(point.fX) && 860c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkScalarIsFinite(point.fY) && 870c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkScalarIsFinite(point.fZ)); 880c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed return point; 890c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed}; 900c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 91959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillipsstatic void write_point3(const SkPoint3& point, SkWriteBuffer& buffer) { 920c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed buffer.writeScalar(point.fX); 930c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed buffer.writeScalar(point.fY); 940c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed buffer.writeScalar(point.fZ); 950c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed}; 960c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 970c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedclass GrGLLight; 980c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedclass SkImageFilterLight : public SkRefCnt { 990c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedpublic: 1000c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed enum LightType { 1010c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed kDistant_LightType, 1020c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed kPoint_LightType, 1030c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed kSpot_LightType, 104959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips 105959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips kLast_LightType = kSpot_LightType 1060c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed }; 1070c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed virtual LightType type() const = 0; 1080c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed const SkPoint3& color() const { return fColor; } 1090c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed virtual GrGLLight* createGLLight() const = 0; 1100c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed virtual bool isEqual(const SkImageFilterLight& other) const { 1110c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed return fColor == other.fColor; 1120c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed } 1130c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed virtual SkImageFilterLight* transform(const SkMatrix& matrix) const = 0; 1140c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 1150c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed virtual sk_sp<SkImageFilterLight> makeColorSpace(SkColorSpaceXformer*) const = 0; 1160c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 1170c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed // Defined below SkLight's subclasses. 1180c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed void flattenLight(SkWriteBuffer& buffer) const; 1190c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed static SkImageFilterLight* UnflattenLight(SkReadBuffer& buffer); 1200c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 1210c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed virtual SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const = 0; 1220c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed virtual SkPoint3 lightColor(const SkPoint3& surfaceToLight) const = 0; 1230c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 1240c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedprotected: 1250c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkImageFilterLight(SkColor color) { 1260c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed fColor = SkPoint3::Make(SkIntToScalar(SkColorGetR(color)), 1270c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkIntToScalar(SkColorGetG(color)), 1280c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkIntToScalar(SkColorGetB(color))); 1290c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed } 130959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips SkImageFilterLight(const SkPoint3& color) : fColor(color) {} 131959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips 1320c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkImageFilterLight(SkReadBuffer& buffer) { 133959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips fColor = read_point3(buffer); 1340c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed } 1350c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 1360c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed virtual void onFlattenLight(SkWriteBuffer& buffer) const = 0; 1370c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 1380c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 1390c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedprivate: 1400c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed typedef SkRefCnt INHERITED; 1410c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkPoint3 fColor; 1420c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed}; 1430c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 1440c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedclass BaseLightingType { 1450c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedpublic: 1460c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed BaseLightingType() {} 1470c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed virtual ~BaseLightingType() {} 1480c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 1490c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed virtual SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, 1500c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed const SkPoint3& lightColor) const= 0; 1510c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed}; 1520c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed 1530c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedclass DiffuseLightingType : public BaseLightingType { 154f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgpublic: 155f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org DiffuseLightingType(SkScalar kd) 156f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org : fKD(kd) {} 157b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, 1580c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed const SkPoint3& lightColor) const override { 1598be952ad8c9deefe19cff36f9ad217563400f817Mike Reed SkScalar colorScale = fKD * normal.dot(surfaceTolight); 160f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org colorScale = SkScalarClampMax(colorScale, SK_Scalar1); 1613d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkPoint3 color = lightColor.makeScale(colorScale); 162f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return SkPackARGB32(255, 163b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org SkClampMax(SkScalarRoundToInt(color.fX), 255), 164b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org SkClampMax(SkScalarRoundToInt(color.fY), 255), 165b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org SkClampMax(SkScalarRoundToInt(color.fZ), 255)); 166f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 167f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgprivate: 168f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar fKD; 169f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org}; 170f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 1713d32d768cd8b66c49c070495c08f7933b9dd2423robertphillipsstatic SkScalar max_component(const SkPoint3& p) { 1723d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips return p.x() > p.y() ? (p.x() > p.z() ? p.x() : p.z()) : (p.y() > p.z() ? p.y() : p.z()); 1733d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips} 1743d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips 1750c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedclass SpecularLightingType : public BaseLightingType { 176f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgpublic: 177f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SpecularLightingType(SkScalar ks, SkScalar shininess) 178f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org : fKS(ks), fShininess(shininess) {} 179b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, 1800c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed const SkPoint3& lightColor) const override { 181f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkPoint3 halfDir(surfaceTolight); 182f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org halfDir.fZ += SK_Scalar1; // eye position is always (0, 0, 1) 183992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth fast_normalize(&halfDir); 1848be952ad8c9deefe19cff36f9ad217563400f817Mike Reed SkScalar colorScale = fKS * SkScalarPow(normal.dot(halfDir), fShininess); 185f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org colorScale = SkScalarClampMax(colorScale, SK_Scalar1); 1863d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkPoint3 color = lightColor.makeScale(colorScale); 1873d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips return SkPackARGB32(SkClampMax(SkScalarRoundToInt(max_component(color)), 255), 188b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org SkClampMax(SkScalarRoundToInt(color.fX), 255), 189b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org SkClampMax(SkScalarRoundToInt(color.fY), 255), 190b9c95978c614e8f6bc00bdf565cff57388d8c659senorblanco@chromium.org SkClampMax(SkScalarRoundToInt(color.fZ), 255)); 191f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 192f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgprivate: 193f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar fKS; 194f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar fShininess; 195f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org}; 196f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 19762745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkScalar sobel(int a, int b, int c, int d, int e, int f, SkScalar scale) { 1988be952ad8c9deefe19cff36f9ad217563400f817Mike Reed return (-a + b - 2 * c + 2 * d -e + f) * scale; 199f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 200f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 20162745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkPoint3 pointToNormal(SkScalar x, SkScalar y, SkScalar surfaceScale) { 2028be952ad8c9deefe19cff36f9ad217563400f817Mike Reed SkPoint3 vector = SkPoint3::Make(-x * surfaceScale, -y * surfaceScale, 1); 203992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth fast_normalize(&vector); 204f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return vector; 205f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 206f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 20762745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkPoint3 topLeftNormal(int m[9], SkScalar surfaceScale) { 208f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return pointToNormal(sobel(0, 0, m[4], m[5], m[7], m[8], gTwoThirds), 209f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org sobel(0, 0, m[4], m[7], m[5], m[8], gTwoThirds), 210f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceScale); 211f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 212f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 21362745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkPoint3 topNormal(int m[9], SkScalar surfaceScale) { 214f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return pointToNormal(sobel( 0, 0, m[3], m[5], m[6], m[8], gOneThird), 215f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org sobel(m[3], m[6], m[4], m[7], m[5], m[8], gOneHalf), 216f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceScale); 217f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 218f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 21962745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkPoint3 topRightNormal(int m[9], SkScalar surfaceScale) { 220f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return pointToNormal(sobel( 0, 0, m[3], m[4], m[6], m[7], gTwoThirds), 221f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org sobel(m[3], m[6], m[4], m[7], 0, 0, gTwoThirds), 222f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceScale); 223f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 224f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 22562745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkPoint3 leftNormal(int m[9], SkScalar surfaceScale) { 226f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return pointToNormal(sobel(m[1], m[2], m[4], m[5], m[7], m[8], gOneHalf), 227f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org sobel( 0, 0, m[1], m[7], m[2], m[8], gOneThird), 228f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceScale); 229f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 230f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 231f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 23262745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkPoint3 interiorNormal(int m[9], SkScalar surfaceScale) { 233f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return pointToNormal(sobel(m[0], m[2], m[3], m[5], m[6], m[8], gOneQuarter), 234f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org sobel(m[0], m[6], m[1], m[7], m[2], m[8], gOneQuarter), 235f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceScale); 236f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 237f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 23862745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkPoint3 rightNormal(int m[9], SkScalar surfaceScale) { 239f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return pointToNormal(sobel(m[0], m[1], m[3], m[4], m[6], m[7], gOneHalf), 240f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org sobel(m[0], m[6], m[1], m[7], 0, 0, gOneThird), 241f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceScale); 242f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 243f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 24462745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkPoint3 bottomLeftNormal(int m[9], SkScalar surfaceScale) { 245f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return pointToNormal(sobel(m[1], m[2], m[4], m[5], 0, 0, gTwoThirds), 246f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org sobel( 0, 0, m[1], m[4], m[2], m[5], gTwoThirds), 247f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceScale); 248f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 249f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 25062745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkPoint3 bottomNormal(int m[9], SkScalar surfaceScale) { 251f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return pointToNormal(sobel(m[0], m[2], m[3], m[5], 0, 0, gOneThird), 252f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org sobel(m[0], m[3], m[1], m[4], m[2], m[5], gOneHalf), 253f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceScale); 254f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 255f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 25662745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic inline SkPoint3 bottomRightNormal(int m[9], SkScalar surfaceScale) { 257f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return pointToNormal(sobel(m[0], m[1], m[3], m[4], 0, 0, gTwoThirds), 258f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org sobel(m[0], m[3], m[1], m[4], 0, 0, gTwoThirds), 259f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceScale); 260f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 261f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 26284f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco 26384f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblancoclass UncheckedPixelFetcher { 26484f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblancopublic: 26584f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco static inline uint32_t Fetch(const SkBitmap& src, int x, int y, const SkIRect& bounds) { 26684f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco return SkGetPackedA32(*src.getAddr32(x, y)); 26784f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco } 26884f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco}; 26984f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco 27084f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco// The DecalPixelFetcher is used when the destination crop rect exceeds the input bitmap bounds. 27184f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblancoclass DecalPixelFetcher { 27284f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblancopublic: 27384f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco static inline uint32_t Fetch(const SkBitmap& src, int x, int y, const SkIRect& bounds) { 27484f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco if (x < bounds.fLeft || x >= bounds.fRight || y < bounds.fTop || y >= bounds.fBottom) { 27584f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco return 0; 27684f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco } else { 27784f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco return SkGetPackedA32(*src.getAddr32(x, y)); 27884f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco } 27984f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco } 28084f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco}; 28184f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco 2820c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedtemplate <class PixelFetcher> 2830c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedstatic void lightBitmap(const BaseLightingType& lightingType, 2840c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed const SkImageFilterLight* l, 28584f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco const SkBitmap& src, 28684f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco SkBitmap* dst, 28784f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco SkScalar surfaceScale, 28884f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco const SkIRect& bounds) { 2894e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkASSERT(dst->width() == bounds.width() && dst->height() == bounds.height()); 2904e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org int left = bounds.left(), right = bounds.right(); 2914e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org int bottom = bounds.bottom(); 2924e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org int y = bounds.top(); 29384f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco SkIRect srcBounds = src.bounds(); 2944e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkPMColor* dptr = dst->getAddr32(0, 0); 295f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org { 2964e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org int x = left; 297f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org int m[9]; 29884f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[4] = PixelFetcher::Fetch(src, x, y, srcBounds); 29984f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[5] = PixelFetcher::Fetch(src, x + 1, y, srcBounds); 30084f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[7] = PixelFetcher::Fetch(src, x, y + 1, srcBounds); 30184f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[8] = PixelFetcher::Fetch(src, x + 1, y + 1, srcBounds); 302f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); 303b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *dptr++ = lightingType.light(topLeftNormal(m, surfaceScale), surfaceToLight, 304b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt l->lightColor(surfaceToLight)); 3054e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org for (++x; x < right - 1; ++x) 306f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org { 307f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org shiftMatrixLeft(m); 30884f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[5] = PixelFetcher::Fetch(src, x + 1, y, srcBounds); 30984f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[8] = PixelFetcher::Fetch(src, x + 1, y + 1, srcBounds); 3104e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); 311b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *dptr++ = lightingType.light(topNormal(m, surfaceScale), surfaceToLight, 312b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt l->lightColor(surfaceToLight)); 313f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 314f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org shiftMatrixLeft(m); 315f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); 316b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *dptr++ = lightingType.light(topRightNormal(m, surfaceScale), surfaceToLight, 317b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt l->lightColor(surfaceToLight)); 318f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 319f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 3204e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org for (++y; y < bottom - 1; ++y) { 3214e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org int x = left; 322f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org int m[9]; 32384f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[1] = PixelFetcher::Fetch(src, x, y - 1, srcBounds); 32484f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[2] = PixelFetcher::Fetch(src, x + 1, y - 1, srcBounds); 32584f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[4] = PixelFetcher::Fetch(src, x, y, srcBounds); 32684f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[5] = PixelFetcher::Fetch(src, x + 1, y, srcBounds); 32784f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[7] = PixelFetcher::Fetch(src, x, y + 1, srcBounds); 32884f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[8] = PixelFetcher::Fetch(src, x + 1, y + 1, srcBounds); 329f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); 330b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *dptr++ = lightingType.light(leftNormal(m, surfaceScale), surfaceToLight, 331b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt l->lightColor(surfaceToLight)); 3324e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org for (++x; x < right - 1; ++x) { 333f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org shiftMatrixLeft(m); 33484f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[2] = PixelFetcher::Fetch(src, x + 1, y - 1, srcBounds); 33584f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[5] = PixelFetcher::Fetch(src, x + 1, y, srcBounds); 33684f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[8] = PixelFetcher::Fetch(src, x + 1, y + 1, srcBounds); 337f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); 338b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *dptr++ = lightingType.light(interiorNormal(m, surfaceScale), surfaceToLight, 339b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt l->lightColor(surfaceToLight)); 340f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 341f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org shiftMatrixLeft(m); 342f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); 343b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *dptr++ = lightingType.light(rightNormal(m, surfaceScale), surfaceToLight, 344b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt l->lightColor(surfaceToLight)); 345f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 346f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 347f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org { 3484e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org int x = left; 349f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org int m[9]; 35084f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[1] = PixelFetcher::Fetch(src, x, bottom - 2, srcBounds); 35184f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[2] = PixelFetcher::Fetch(src, x + 1, bottom - 2, srcBounds); 35284f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[4] = PixelFetcher::Fetch(src, x, bottom - 1, srcBounds); 35384f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[5] = PixelFetcher::Fetch(src, x + 1, bottom - 1, srcBounds); 354f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); 355b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *dptr++ = lightingType.light(bottomLeftNormal(m, surfaceScale), surfaceToLight, 356b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt l->lightColor(surfaceToLight)); 3574e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org for (++x; x < right - 1; ++x) 358f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org { 359f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org shiftMatrixLeft(m); 36084f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[2] = PixelFetcher::Fetch(src, x + 1, bottom - 2, srcBounds); 36184f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco m[5] = PixelFetcher::Fetch(src, x + 1, bottom - 1, srcBounds); 362f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); 363b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *dptr++ = lightingType.light(bottomNormal(m, surfaceScale), surfaceToLight, 364b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt l->lightColor(surfaceToLight)); 365f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 366f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org shiftMatrixLeft(m); 367f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); 368b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *dptr++ = lightingType.light(bottomRightNormal(m, surfaceScale), surfaceToLight, 369b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt l->lightColor(surfaceToLight)); 370f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 371f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 372f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 3730c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reedstatic void lightBitmap(const BaseLightingType& lightingType, 37484f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco const SkImageFilterLight* light, 37584f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco const SkBitmap& src, 37684f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco SkBitmap* dst, 37784f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco SkScalar surfaceScale, 37884f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco const SkIRect& bounds) { 37984f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco if (src.bounds().contains(bounds)) { 3800c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed lightBitmap<UncheckedPixelFetcher>( 38184f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco lightingType, light, src, dst, surfaceScale, bounds); 38284f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco } else { 3830c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed lightBitmap<DecalPixelFetcher>( 38484f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco lightingType, light, src, dst, surfaceScale, bounds); 38584f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco } 38684f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco} 38784f0e745839a0cb5ff5055f5ea0726bdd83b920bsenorblanco 388d0d37cace08f12abf8d316e6949e947551d418e6senorblancoenum BoundaryMode { 389d0d37cace08f12abf8d316e6949e947551d418e6senorblanco kTopLeft_BoundaryMode, 390d0d37cace08f12abf8d316e6949e947551d418e6senorblanco kTop_BoundaryMode, 391d0d37cace08f12abf8d316e6949e947551d418e6senorblanco kTopRight_BoundaryMode, 392d0d37cace08f12abf8d316e6949e947551d418e6senorblanco kLeft_BoundaryMode, 393d0d37cace08f12abf8d316e6949e947551d418e6senorblanco kInterior_BoundaryMode, 394d0d37cace08f12abf8d316e6949e947551d418e6senorblanco kRight_BoundaryMode, 395d0d37cace08f12abf8d316e6949e947551d418e6senorblanco kBottomLeft_BoundaryMode, 396d0d37cace08f12abf8d316e6949e947551d418e6senorblanco kBottom_BoundaryMode, 397d0d37cace08f12abf8d316e6949e947551d418e6senorblanco kBottomRight_BoundaryMode, 398d0d37cace08f12abf8d316e6949e947551d418e6senorblanco 399d0d37cace08f12abf8d316e6949e947551d418e6senorblanco kBoundaryModeCount, 400d0d37cace08f12abf8d316e6949e947551d418e6senorblanco}; 401d0d37cace08f12abf8d316e6949e947551d418e6senorblanco 402d0d37cace08f12abf8d316e6949e947551d418e6senorblancoclass SkLightingImageFilterInternal : public SkLightingImageFilter { 403d0d37cace08f12abf8d316e6949e947551d418e6senorblancoprotected: 40412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkLightingImageFilterInternal(sk_sp<SkImageFilterLight> light, 405d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar surfaceScale, 40612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 407d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const CropRect* cropRect) 40812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips : INHERITED(std::move(light), surfaceScale, std::move(input), cropRect) { 40912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips } 410d0d37cace08f12abf8d316e6949e947551d418e6senorblanco 411d0d37cace08f12abf8d316e6949e947551d418e6senorblanco#if SK_SUPPORT_GPU 412fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein sk_sp<SkSpecialImage> filterImageGPU(SkSpecialImage* source, 413ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkSpecialImage* input, 414ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips const SkIRect& bounds, 4152a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman const SkMatrix& matrix, 4162a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman const OutputProperties& outputProperties) const; 417aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon virtual std::unique_ptr<GrFragmentProcessor> makeFragmentProcessor( 418aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon sk_sp<GrTextureProxy>, 419aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkMatrix&, 420aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkIRect* srcBounds, 421aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon BoundaryMode boundaryMode) const = 0; 422d0d37cace08f12abf8d316e6949e947551d418e6senorblanco#endif 423d0d37cace08f12abf8d316e6949e947551d418e6senorblancoprivate: 424d0d37cace08f12abf8d316e6949e947551d418e6senorblanco#if SK_SUPPORT_GPU 425296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips void drawRect(GrRenderTargetContext*, 4268e1c4e672553ecae2745168514240705f3516773Robert Phillips sk_sp<GrTextureProxy> srcProxy, 427d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkMatrix& matrix, 428d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const GrClip& clip, 429d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkRect& dstRect, 430d0d37cace08f12abf8d316e6949e947551d418e6senorblanco BoundaryMode boundaryMode, 4319bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco const SkIRect* srcBounds, 432d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkIRect& bounds) const; 433d0d37cace08f12abf8d316e6949e947551d418e6senorblanco#endif 434d0d37cace08f12abf8d316e6949e947551d418e6senorblanco typedef SkLightingImageFilter INHERITED; 435d0d37cace08f12abf8d316e6949e947551d418e6senorblanco}; 436d0d37cace08f12abf8d316e6949e947551d418e6senorblanco 437d0d37cace08f12abf8d316e6949e947551d418e6senorblanco#if SK_SUPPORT_GPU 438296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillipsvoid SkLightingImageFilterInternal::drawRect(GrRenderTargetContext* renderTargetContext, 4398e1c4e672553ecae2745168514240705f3516773Robert Phillips sk_sp<GrTextureProxy> srcProxy, 440d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkMatrix& matrix, 441d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const GrClip& clip, 442d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkRect& dstRect, 443d0d37cace08f12abf8d316e6949e947551d418e6senorblanco BoundaryMode boundaryMode, 4449bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco const SkIRect* srcBounds, 445d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkIRect& bounds) const { 446d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkRect srcRect = dstRect.makeOffset(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y())); 447d0d37cace08f12abf8d316e6949e947551d418e6senorblanco GrPaint paint; 448f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon paint.setGammaCorrect(renderTargetContext->colorSpaceInfo().isGammaCorrect()); 449aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon auto fp = this->makeFragmentProcessor(std::move(srcProxy), matrix, srcBounds, boundaryMode); 45006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman paint.addColorFragmentProcessor(std::move(fp)); 451374772bd61951f01bf84fe17bf53d8867681c9aereed paint.setPorterDuffXPFactory(SkBlendMode::kSrc); 45282f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon renderTargetContext->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), dstRect, 45382f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon srcRect); 454d0d37cace08f12abf8d316e6949e947551d418e6senorblanco} 455d0d37cace08f12abf8d316e6949e947551d418e6senorblanco 4562a75e5df300a2838f943ca52a52a85a5cf69802bbrianosmansk_sp<SkSpecialImage> SkLightingImageFilterInternal::filterImageGPU( 4572a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkSpecialImage* source, 4582a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkSpecialImage* input, 4592a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman const SkIRect& offsetBounds, 4602a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman const SkMatrix& matrix, 4612a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman const OutputProperties& outputProperties) const { 462ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkASSERT(source->isTextureBacked()); 463ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 464ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips GrContext* context = source->getContext(); 465ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 4668e1c4e672553ecae2745168514240705f3516773Robert Phillips sk_sp<GrTextureProxy> inputProxy(input->asTextureProxyRef(context)); 4678e1c4e672553ecae2745168514240705f3516773Robert Phillips SkASSERT(inputProxy); 468d0d37cace08f12abf8d316e6949e947551d418e6senorblanco 4697f6cd90f0c8f6e8dd658cb1b1c587b833adfc364Robert Phillips sk_sp<GrRenderTargetContext> renderTargetContext(context->makeDeferredRenderTargetContext( 4707f6cd90f0c8f6e8dd658cb1b1c587b833adfc364Robert Phillips SkBackingFit::kApprox, offsetBounds.width(), offsetBounds.height(), 4717f6cd90f0c8f6e8dd658cb1b1c587b833adfc364Robert Phillips GrRenderableConfigForColorSpace(outputProperties.colorSpace()), 4727f6cd90f0c8f6e8dd658cb1b1c587b833adfc364Robert Phillips sk_ref_sp(outputProperties.colorSpace()))); 4731105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman if (!renderTargetContext) { 474ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 475d0d37cace08f12abf8d316e6949e947551d418e6senorblanco } 476d0d37cace08f12abf8d316e6949e947551d418e6senorblanco 477846c051a4800b3cea341a0195db24297d6d9047fcdalton SkIRect dstIRect = SkIRect::MakeWH(offsetBounds.width(), offsetBounds.height()); 478846c051a4800b3cea341a0195db24297d6d9047fcdalton SkRect dstRect = SkRect::Make(dstIRect); 479ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 480d0d37cace08f12abf8d316e6949e947551d418e6senorblanco // setup new clip 481846c051a4800b3cea341a0195db24297d6d9047fcdalton GrFixedClip clip(dstIRect); 482d0d37cace08f12abf8d316e6949e947551d418e6senorblanco 483ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips const SkIRect inputBounds = SkIRect::MakeWH(input->width(), input->height()); 484d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkRect topLeft = SkRect::MakeXYWH(0, 0, 1, 1); 485d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkRect top = SkRect::MakeXYWH(1, 0, dstRect.width() - 2, 1); 486d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkRect topRight = SkRect::MakeXYWH(dstRect.width() - 1, 0, 1, 1); 487d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkRect left = SkRect::MakeXYWH(0, 1, 1, dstRect.height() - 2); 488d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkRect interior = dstRect.makeInset(1, 1); 489d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkRect right = SkRect::MakeXYWH(dstRect.width() - 1, 1, 1, dstRect.height() - 2); 490d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkRect bottomLeft = SkRect::MakeXYWH(0, dstRect.height() - 1, 1, 1); 491d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkRect bottom = SkRect::MakeXYWH(1, dstRect.height() - 1, dstRect.width() - 2, 1); 492d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkRect bottomRight = SkRect::MakeXYWH(dstRect.width() - 1, dstRect.height() - 1, 1, 1); 493ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips 494ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips const SkIRect* pSrcBounds = inputBounds.contains(offsetBounds) ? nullptr : &inputBounds; 495296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips this->drawRect(renderTargetContext.get(), inputProxy, matrix, clip, topLeft, 496ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips kTopLeft_BoundaryMode, pSrcBounds, offsetBounds); 497296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips this->drawRect(renderTargetContext.get(), inputProxy, matrix, clip, top, 4981105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman kTop_BoundaryMode, pSrcBounds, offsetBounds); 499296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips this->drawRect(renderTargetContext.get(), inputProxy, matrix, clip, topRight, 500ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips kTopRight_BoundaryMode, pSrcBounds, offsetBounds); 501296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips this->drawRect(renderTargetContext.get(), inputProxy, matrix, clip, left, 5021105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman kLeft_BoundaryMode, pSrcBounds, offsetBounds); 503296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips this->drawRect(renderTargetContext.get(), inputProxy, matrix, clip, interior, 504ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips kInterior_BoundaryMode, pSrcBounds, offsetBounds); 505296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips this->drawRect(renderTargetContext.get(), inputProxy, matrix, clip, right, 5061105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman kRight_BoundaryMode, pSrcBounds, offsetBounds); 507296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips this->drawRect(renderTargetContext.get(), inputProxy, matrix, clip, bottomLeft, 508ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips kBottomLeft_BoundaryMode, pSrcBounds, offsetBounds); 509296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips this->drawRect(renderTargetContext.get(), inputProxy, matrix, clip, bottom, 510ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips kBottom_BoundaryMode, pSrcBounds, offsetBounds); 511296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips this->drawRect(renderTargetContext.get(), inputProxy, matrix, clip, bottomRight, 512ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips kBottomRight_BoundaryMode, pSrcBounds, offsetBounds); 513ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 5147f6cd90f0c8f6e8dd658cb1b1c587b833adfc364Robert Phillips return SkSpecialImage::MakeDeferredFromGpu( 515f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon context, 516f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon SkIRect::MakeWH(offsetBounds.width(), offsetBounds.height()), 517f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon kNeedNewImageUniqueID_SpecialImage, 518f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon renderTargetContext->asTextureProxyRef(), 519f3569f0f6d312570c7344b345f8b3a03a892f751Brian Salomon renderTargetContext->colorSpaceInfo().refColorSpace()); 520d0d37cace08f12abf8d316e6949e947551d418e6senorblanco} 521d0d37cace08f12abf8d316e6949e947551d418e6senorblanco#endif 522d0d37cace08f12abf8d316e6949e947551d418e6senorblanco 523d0d37cace08f12abf8d316e6949e947551d418e6senorblancoclass SkDiffuseLightingImageFilter : public SkLightingImageFilterInternal { 524f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgpublic: 52512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips static sk_sp<SkImageFilter> Make(sk_sp<SkImageFilterLight> light, 52612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, 52712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar kd, 52812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter>, 52912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const CropRect*); 5309fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 531f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips SK_TO_STRING_OVERRIDE() 532f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiffuseLightingImageFilter) 533bdb1ec453a36b3e8e8800713aef0dce934e6a6a7senorblanco@chromium.org SkScalar kd() const { return fKD; } 534bdb1ec453a36b3e8e8800713aef0dce934e6a6a7senorblanco@chromium.org 535f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgprotected: 53612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkDiffuseLightingImageFilter(sk_sp<SkImageFilterLight> light, SkScalar surfaceScale, 53712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar kd, 53812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, const CropRect* cropRect); 53936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void flatten(SkWriteBuffer& buffer) const override; 540ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 541ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&, 542ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkIPoint* offset) const override; 54362745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override; 544ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 5451aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org#if SK_SUPPORT_GPU 546aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon std::unique_ptr<GrFragmentProcessor> makeFragmentProcessor(sk_sp<GrTextureProxy>, 547aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkMatrix&, 548aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkIRect* bounds, 549aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon BoundaryMode) const override; 5501aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org#endif 551f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 552f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgprivate: 5539fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed friend class SkLightingImageFilter; 554f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar fKD; 555ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 556ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips typedef SkLightingImageFilterInternal INHERITED; 557f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org}; 558f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 559d0d37cace08f12abf8d316e6949e947551d418e6senorblancoclass SkSpecularLightingImageFilter : public SkLightingImageFilterInternal { 560f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgpublic: 56112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips static sk_sp<SkImageFilter> Make(sk_sp<SkImageFilterLight> light, 56212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, 56312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar ks, SkScalar shininess, 56412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter>, const CropRect*); 5659fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 566f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips SK_TO_STRING_OVERRIDE() 567f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSpecularLightingImageFilter) 568f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 569894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar ks() const { return fKS; } 570894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar shininess() const { return fShininess; } 571894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 572f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgprotected: 57312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkSpecularLightingImageFilter(sk_sp<SkImageFilterLight> light, 57412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, SkScalar ks, 57512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar shininess, 57612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, const CropRect*); 57736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void flatten(SkWriteBuffer& buffer) const override; 578ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 579ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&, 580ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkIPoint* offset) const override; 58162745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override; 582ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 5831aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org#if SK_SUPPORT_GPU 584aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon std::unique_ptr<GrFragmentProcessor> makeFragmentProcessor(sk_sp<GrTextureProxy>, 585aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkMatrix&, 586aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkIRect* bounds, 587aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon BoundaryMode) const override; 5881aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org#endif 589f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 590f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgprivate: 591f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar fKS; 592f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar fShininess; 5939fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed friend class SkLightingImageFilter; 594d0d37cace08f12abf8d316e6949e947551d418e6senorblanco typedef SkLightingImageFilterInternal INHERITED; 595f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org}; 596f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 597cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 598894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 5996cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomonclass GrLightingEffect : public GrFragmentProcessor { 600894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgpublic: 6016b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon const SkImageFilterLight* light() const { return fLight.get(); } 602894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar surfaceScale() const { return fSurfaceScale; } 603fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org const SkMatrix& filterMatrix() const { return fFilterMatrix; } 604d0d37cace08f12abf8d316e6949e947551d418e6senorblanco BoundaryMode boundaryMode() const { return fBoundaryMode; } 6059bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco const GrTextureDomain& domain() const { return fDomain; } 606371e105da5d9fdfff3b4242b37ff6fc09214c8c8bsalomon@google.com 607b4b7a4c9ea2e399db550f93e3754c351e5b2079arobertphillipsprotected: 608abff956455637b12eab374fd44b99e1338799113Ethan Nicholas GrLightingEffect(ClassID classID, sk_sp<GrTextureProxy>, sk_sp<const SkImageFilterLight> light, 6096b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon SkScalar surfaceScale, const SkMatrix& matrix, BoundaryMode boundaryMode, 6106b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon const SkIRect* srcBounds); 6116b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon 6126b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon GrLightingEffect(const GrLightingEffect& that); 613b4b7a4c9ea2e399db550f93e3754c351e5b2079arobertphillips 6141c9686bfa5e2de3e06f1d1b9691105afb6659e85Robert Phillips bool onIsEqual(const GrFragmentProcessor&) const override; 6151a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel 616894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgprivate: 6176cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon GrCoordTransform fCoordTransform; 6186cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon GrTextureDomain fDomain; 6196cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon TextureSampler fTextureSampler; 6206b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon sk_sp<const SkImageFilterLight> fLight; 621894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar fSurfaceScale; 622fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix fFilterMatrix; 623d0d37cace08f12abf8d316e6949e947551d418e6senorblanco BoundaryMode fBoundaryMode; 6242f0dbc761a626473c19db7de561c7072b12953c5robertphillips 6256cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon typedef GrFragmentProcessor INHERITED; 626894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org}; 627894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 628894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgclass GrDiffuseLightingEffect : public GrLightingEffect { 629894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgpublic: 630aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy, 631aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon sk_sp<const SkImageFilterLight> light, 632aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon SkScalar surfaceScale, 633aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkMatrix& matrix, 634aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon SkScalar kd, 635aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon BoundaryMode boundaryMode, 636aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkIRect* srcBounds) { 637aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon return std::unique_ptr<GrFragmentProcessor>( 6386b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon new GrDiffuseLightingEffect(std::move(proxy), std::move(light), surfaceScale, 6396b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon matrix, kd, boundaryMode, srcBounds)); 6400ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com } 641894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 64236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "DiffuseLighting"; } 643eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 644aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon std::unique_ptr<GrFragmentProcessor> clone() const override { 645aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon return std::unique_ptr<GrFragmentProcessor>(new GrDiffuseLightingEffect(*this)); 6466b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon } 6476b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon 648894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar kd() const { return fKD; } 64968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 650894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgprivate: 65157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; 652b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix 65394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 6544b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix 65536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onIsEqual(const GrFragmentProcessor&) const override; 65668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 657fbcef6eb8abad142daf45418516550f7635b4a52Robert Phillips GrDiffuseLightingEffect(sk_sp<GrTextureProxy>, 6586b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon sk_sp<const SkImageFilterLight> light, 6590ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com SkScalar surfaceScale, 660fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org const SkMatrix& matrix, 661d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar kd, 6629bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco BoundaryMode boundaryMode, 6639bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco const SkIRect* srcBounds); 6640ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 6656b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon explicit GrDiffuseLightingEffect(const GrDiffuseLightingEffect& that); 6666b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon 6670c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon GR_DECLARE_FRAGMENT_PROCESSOR_TEST 668696b29346e85307a05af47768d358161eba3f6bdRobert Phillips SkScalar fKD; 6698e1c4e672553ecae2745168514240705f3516773Robert Phillips 6708e1c4e672553ecae2745168514240705f3516773Robert Phillips typedef GrLightingEffect INHERITED; 671894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org}; 672894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 673894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgclass GrSpecularLightingEffect : public GrLightingEffect { 674894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgpublic: 675aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy, 676aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon sk_sp<const SkImageFilterLight> light, 677aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon SkScalar surfaceScale, 678aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkMatrix& matrix, 679aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon SkScalar ks, 680aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon SkScalar shininess, 681aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon BoundaryMode boundaryMode, 682aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkIRect* srcBounds) { 683aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon return std::unique_ptr<GrFragmentProcessor>( 6846b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon new GrSpecularLightingEffect(std::move(proxy), std::move(light), surfaceScale, 6856b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon matrix, ks, shininess, boundaryMode, srcBounds)); 6860ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com } 687894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 68836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "SpecularLighting"; } 689eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 690aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon std::unique_ptr<GrFragmentProcessor> clone() const override { 691aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon return std::unique_ptr<GrFragmentProcessor>(new GrSpecularLightingEffect(*this)); 6926b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon } 6936b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon 69457d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; 695894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 696894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar ks() const { return fKS; } 697894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar shininess() const { return fShininess; } 698894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 699894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgprivate: 70094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 7014b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix 70236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onIsEqual(const GrFragmentProcessor&) const override; 70368b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 704fbcef6eb8abad142daf45418516550f7635b4a52Robert Phillips GrSpecularLightingEffect(sk_sp<GrTextureProxy>, 7056b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon sk_sp<const SkImageFilterLight> light, 7060ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com SkScalar surfaceScale, 707fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org const SkMatrix& matrix, 7080ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com SkScalar ks, 709d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar shininess, 7109bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco BoundaryMode boundaryMode, 7119bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco const SkIRect* srcBounds); 7120ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 7136b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon explicit GrSpecularLightingEffect(const GrSpecularLightingEffect&); 7146b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon 7150c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon GR_DECLARE_FRAGMENT_PROCESSOR_TEST 716894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar fKS; 717894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar fShininess; 7188e1c4e672553ecae2745168514240705f3516773Robert Phillips 7198e1c4e672553ecae2745168514240705f3516773Robert Phillips typedef GrLightingEffect INHERITED; 720894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org}; 721894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 722894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 723894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 724894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgclass GrGLLight { 725894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgpublic: 7266730cbb80a2366c1333f48b7cd0397daed337a8bsenorblanco@chromium.org virtual ~GrGLLight() {} 727894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 728ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com /** 729ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com * This is called by GrGLLightingEffect::emitCode() before either of the two virtual functions 730f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas * below. It adds a half3 uniform visible in the FS that represents the constant light color. 731ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com */ 7327ea439b2203855db97330b25945b87dd4b170b8begdaniel void emitLightColorUniform(GrGLSLUniformHandler*); 733ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 734e862d16162fd46ad9b2832c8844b00c81bedbac0skia.committer@gmail.com /** 735ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com * These two functions are called from GrGLLightingEffect's emitCode() function. 736ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com * emitSurfaceToLight places an expression in param out that is the vector from the surface to 737ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com * the light. The expression will be used in the FS. emitLightColor writes an expression into 738ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com * the FS that is the color of the light. Either function may add functions and/or uniforms to 739ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com * the FS. The default of emitLightColor appends the name of the constant light color uniform 740ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com * and so this function only needs to be overridden if the light color varies spatially. 741ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com */ 7427ea439b2203855db97330b25945b87dd4b170b8begdaniel virtual void emitSurfaceToLight(GrGLSLUniformHandler*, 7438528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder*, 7447ea439b2203855db97330b25945b87dd4b170b8begdaniel const char* z) = 0; 7457ea439b2203855db97330b25945b87dd4b170b8begdaniel virtual void emitLightColor(GrGLSLUniformHandler*, 7468528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder*, 7474ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel const char *surfaceToLight); 748ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 749ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com // This is called from GrGLLightingEffect's setData(). Subclasses of GrGLLight must call 750ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com // INHERITED::setData(). 751018fb62d12d1febf121fe265da5b6117b86a6541egdaniel virtual void setData(const GrGLSLProgramDataManager&, const SkImageFilterLight* light) const; 752894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 753894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgprotected: 754ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com /** 755ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com * Gets the constant light color uniform. Subclasses can use this in their emitLightColor 756ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com * function. 757ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com */ 758ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com UniformHandle lightColorUni() const { return fColorUni; } 759ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 760ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.comprivate: 761032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fColorUni; 762ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 763ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com typedef SkRefCnt INHERITED; 764894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org}; 765894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 766894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 767894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 768894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgclass GrGLDistantLight : public GrGLLight { 769894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgpublic: 770d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon ~GrGLDistantLight() override {} 771018fb62d12d1febf121fe265da5b6117b86a6541egdaniel void setData(const GrGLSLProgramDataManager&, const SkImageFilterLight* light) const override; 7728528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton void emitSurfaceToLight(GrGLSLUniformHandler*, GrGLSLFPFragmentBuilder*, const char* z) override; 7738d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org 774894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgprivate: 775894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org typedef GrGLLight INHERITED; 776032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fDirectionUni; 777894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org}; 778894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 779894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 780894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 781894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgclass GrGLPointLight : public GrGLLight { 782894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgpublic: 783d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon ~GrGLPointLight() override {} 784018fb62d12d1febf121fe265da5b6117b86a6541egdaniel void setData(const GrGLSLProgramDataManager&, const SkImageFilterLight* light) const override; 7858528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton void emitSurfaceToLight(GrGLSLUniformHandler*, GrGLSLFPFragmentBuilder*, const char* z) override; 7868d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org 787894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgprivate: 788894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org typedef GrGLLight INHERITED; 789032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fLocationUni; 790894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org}; 791894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 792894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 793894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 794894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgclass GrGLSpotLight : public GrGLLight { 795894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgpublic: 796d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon ~GrGLSpotLight() override {} 797018fb62d12d1febf121fe265da5b6117b86a6541egdaniel void setData(const GrGLSLProgramDataManager&, const SkImageFilterLight* light) const override; 7988528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton void emitSurfaceToLight(GrGLSLUniformHandler*, GrGLSLFPFragmentBuilder*, const char* z) override; 7997ea439b2203855db97330b25945b87dd4b170b8begdaniel void emitLightColor(GrGLSLUniformHandler*, 8008528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder*, 8014ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel const char *surfaceToLight) override; 8028d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org 803894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgprivate: 804894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org typedef GrGLLight INHERITED; 805894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 806a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com SkString fLightColorFunc; 807032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fLocationUni; 808032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fExponentUni; 809032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fCosOuterConeAngleUni; 810032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fCosInnerConeAngleUni; 811032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fConeScaleUni; 812032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fSUni; 813894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org}; 814cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else 815cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 816cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comclass GrGLLight; 817cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 818cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 819894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 820894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 821894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 822894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 823894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 82462745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic SkColor xform_color(const SkPoint3& color, SkColorSpaceXformer* xformer) { 82562745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett SkColor origColor = SkColorSetARGBInline(0xFF, 82662745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett SkScalarRoundToInt(color.fX), 82762745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett SkScalarRoundToInt(color.fY), 82862745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett SkScalarRoundToInt(color.fZ)); 82962745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett return xformer->apply(origColor); 83062745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett} 83162745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett 8322f0dbc761a626473c19db7de561c7072b12953c5robertphillipsclass SkDistantLight : public SkImageFilterLight { 833f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgpublic: 834bdb1ec453a36b3e8e8800713aef0dce934e6a6a7senorblanco@chromium.org SkDistantLight(const SkPoint3& direction, SkColor color) 835bdb1ec453a36b3e8e8800713aef0dce934e6a6a7senorblanco@chromium.org : INHERITED(color), fDirection(direction) { 836f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 8370833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com 8380c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const override { 839f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return fDirection; 840fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein } 8410c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkPoint3 lightColor(const SkPoint3&) const override { return this->color(); } 84236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein LightType type() const override { return kDistant_LightType; } 843894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org const SkPoint3& direction() const { return fDirection; } 84436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrGLLight* createGLLight() const override { 845cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 846385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new GrGLDistantLight; 847cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else 848cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com SkDEBUGFAIL("Should not call in GPU-less build"); 84996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 850cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 851cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com } 8528d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org 85362745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett sk_sp<SkImageFilterLight> makeColorSpace(SkColorSpaceXformer* xformer) const override { 85462745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett return sk_make_sp<SkDistantLight>(fDirection, xform_color(this->color(), xformer)); 85562745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett } 85662745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett 8572f0dbc761a626473c19db7de561c7072b12953c5robertphillips bool isEqual(const SkImageFilterLight& other) const override { 8586730cbb80a2366c1333f48b7cd0397daed337a8bsenorblanco@chromium.org if (other.type() != kDistant_LightType) { 8596730cbb80a2366c1333f48b7cd0397daed337a8bsenorblanco@chromium.org return false; 8606730cbb80a2366c1333f48b7cd0397daed337a8bsenorblanco@chromium.org } 8616730cbb80a2366c1333f48b7cd0397daed337a8bsenorblanco@chromium.org 8626730cbb80a2366c1333f48b7cd0397daed337a8bsenorblanco@chromium.org const SkDistantLight& o = static_cast<const SkDistantLight&>(other); 8636730cbb80a2366c1333f48b7cd0397daed337a8bsenorblanco@chromium.org return INHERITED::isEqual(other) && 8646730cbb80a2366c1333f48b7cd0397daed337a8bsenorblanco@chromium.org fDirection == o.fDirection; 8656730cbb80a2366c1333f48b7cd0397daed337a8bsenorblanco@chromium.org } 866f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 8678b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkDistantLight(SkReadBuffer& buffer) : INHERITED(buffer) { 868959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips fDirection = read_point3(buffer); 869790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org } 870f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 8710833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.comprotected: 872fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkDistantLight(const SkPoint3& direction, const SkPoint3& color) 873fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org : INHERITED(color), fDirection(direction) { 874fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org } 8752f0dbc761a626473c19db7de561c7072b12953c5robertphillips SkImageFilterLight* transform(const SkMatrix& matrix) const override { 876fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org return new SkDistantLight(direction(), color()); 877fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org } 87836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onFlattenLight(SkWriteBuffer& buffer) const override { 879959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips write_point3(fDirection, buffer); 8800833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com } 8810833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com 882f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgprivate: 883f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkPoint3 fDirection; 8842f0dbc761a626473c19db7de561c7072b12953c5robertphillips 8852f0dbc761a626473c19db7de561c7072b12953c5robertphillips typedef SkImageFilterLight INHERITED; 886f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org}; 887f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 888894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 889894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 8902f0dbc761a626473c19db7de561c7072b12953c5robertphillipsclass SkPointLight : public SkImageFilterLight { 891f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgpublic: 892bdb1ec453a36b3e8e8800713aef0dce934e6a6a7senorblanco@chromium.org SkPointLight(const SkPoint3& location, SkColor color) 893bdb1ec453a36b3e8e8800713aef0dce934e6a6a7senorblanco@chromium.org : INHERITED(color), fLocation(location) {} 8940833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com 8950c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const override { 8963d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x), 8973d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips fLocation.fY - SkIntToScalar(y), 8988be952ad8c9deefe19cff36f9ad217563400f817Mike Reed fLocation.fZ - SkIntToScalar(z) * surfaceScale); 899992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth fast_normalize(&direction); 900f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return direction; 901fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein } 9020c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkPoint3 lightColor(const SkPoint3&) const override { return this->color(); } 90336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein LightType type() const override { return kPoint_LightType; } 904894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org const SkPoint3& location() const { return fLocation; } 90536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrGLLight* createGLLight() const override { 906cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 907385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new GrGLPointLight; 908cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else 909cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com SkDEBUGFAIL("Should not call in GPU-less build"); 91096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 911cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 912894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org } 91362745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett 91462745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett sk_sp<SkImageFilterLight> makeColorSpace(SkColorSpaceXformer* xformer) const override { 91562745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett return sk_make_sp<SkPointLight>(fLocation, xform_color(this->color(), xformer)); 91662745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett } 91762745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett 9182f0dbc761a626473c19db7de561c7072b12953c5robertphillips bool isEqual(const SkImageFilterLight& other) const override { 919894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org if (other.type() != kPoint_LightType) { 920894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org return false; 921894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org } 922894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org const SkPointLight& o = static_cast<const SkPointLight&>(other); 923894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org return INHERITED::isEqual(other) && 924894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org fLocation == o.fLocation; 925894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org } 9262f0dbc761a626473c19db7de561c7072b12953c5robertphillips SkImageFilterLight* transform(const SkMatrix& matrix) const override { 927fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkPoint location2 = SkPoint::Make(fLocation.fX, fLocation.fY); 928fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org matrix.mapPoints(&location2, 1); 9291037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org // Use X scale and Y scale on Z and average the result 9301037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org SkPoint locationZ = SkPoint::Make(fLocation.fZ, fLocation.fZ); 9311037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org matrix.mapVectors(&locationZ, 1); 9329d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary SkPoint3 location = SkPoint3::Make(location2.fX, 9339d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary location2.fY, 9343d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkScalarAve(locationZ.fX, locationZ.fY)); 935fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org return new SkPointLight(location, color()); 936fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org } 937f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 9388b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkPointLight(SkReadBuffer& buffer) : INHERITED(buffer) { 939959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips fLocation = read_point3(buffer); 9400833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com } 941790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org 942790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.orgprotected: 943fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkPointLight(const SkPoint3& location, const SkPoint3& color) 944fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org : INHERITED(color), fLocation(location) {} 94536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onFlattenLight(SkWriteBuffer& buffer) const override { 946959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips write_point3(fLocation, buffer); 9470833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com } 9480833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com 949f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgprivate: 950f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkPoint3 fLocation; 9512f0dbc761a626473c19db7de561c7072b12953c5robertphillips 9522f0dbc761a626473c19db7de561c7072b12953c5robertphillips typedef SkImageFilterLight INHERITED; 953f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org}; 954f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 955894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 956894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 9572f0dbc761a626473c19db7de561c7072b12953c5robertphillipsclass SkSpotLight : public SkImageFilterLight { 958f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgpublic: 959d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkSpotLight(const SkPoint3& location, 960d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkPoint3& target, 961d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar specularExponent, 962d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar cutoffAngle, 963d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkColor color) 964bdb1ec453a36b3e8e8800713aef0dce934e6a6a7senorblanco@chromium.org : INHERITED(color), 965bdb1ec453a36b3e8e8800713aef0dce934e6a6a7senorblanco@chromium.org fLocation(location), 966f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org fTarget(target), 96762745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett fSpecularExponent(SkScalarPin(specularExponent, kSpecularExponentMin, kSpecularExponentMax)), 96862745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett fCutoffAngle(cutoffAngle) 969f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org { 970f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org fS = target - location; 971992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth fast_normalize(&fS); 972f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org fCosOuterConeAngle = SkScalarCos(SkDegreesToRadians(cutoffAngle)); 9734b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org const SkScalar antiAliasThreshold = 0.016f; 974f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org fCosInnerConeAngle = fCosOuterConeAngle + antiAliasThreshold; 975f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org fConeScale = SkScalarInvert(antiAliasThreshold); 976f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 9770833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com 97862745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett sk_sp<SkImageFilterLight> makeColorSpace(SkColorSpaceXformer* xformer) const override { 97962745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett return sk_make_sp<SkSpotLight>(fLocation, fTarget, fSpecularExponent, fCutoffAngle, 98062745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett xform_color(this->color(), xformer)); 98162745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett } 98262745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett 9832f0dbc761a626473c19db7de561c7072b12953c5robertphillips SkImageFilterLight* transform(const SkMatrix& matrix) const override { 984fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkPoint location2 = SkPoint::Make(fLocation.fX, fLocation.fY); 985fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org matrix.mapPoints(&location2, 1); 9861037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org // Use X scale and Y scale on Z and average the result 9871037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org SkPoint locationZ = SkPoint::Make(fLocation.fZ, fLocation.fZ); 9881037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org matrix.mapVectors(&locationZ, 1); 9893d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkPoint3 location = SkPoint3::Make(location2.fX, location2.fY, 9903d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkScalarAve(locationZ.fX, locationZ.fY)); 991fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkPoint target2 = SkPoint::Make(fTarget.fX, fTarget.fY); 992fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org matrix.mapPoints(&target2, 1); 9931037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org SkPoint targetZ = SkPoint::Make(fTarget.fZ, fTarget.fZ); 9941037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org matrix.mapVectors(&targetZ, 1); 9953d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkPoint3 target = SkPoint3::Make(target2.fX, target2.fY, 9963d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkScalarAve(targetZ.fX, targetZ.fY)); 9971037d92bbc10cafb61d050638e8cbe5a3aa6706fcommit-bot@chromium.org SkPoint3 s = target - location; 998992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth fast_normalize(&s); 999d0d37cace08f12abf8d316e6949e947551d418e6senorblanco return new SkSpotLight(location, 1000d0d37cace08f12abf8d316e6949e947551d418e6senorblanco target, 1001d0d37cace08f12abf8d316e6949e947551d418e6senorblanco fSpecularExponent, 1002d0d37cace08f12abf8d316e6949e947551d418e6senorblanco fCosOuterConeAngle, 1003d0d37cace08f12abf8d316e6949e947551d418e6senorblanco fCosInnerConeAngle, 1004d0d37cace08f12abf8d316e6949e947551d418e6senorblanco fConeScale, 1005d0d37cace08f12abf8d316e6949e947551d418e6senorblanco s, 1006d0d37cace08f12abf8d316e6949e947551d418e6senorblanco color()); 1007fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org } 1008fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org 10090c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const override { 10103d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x), 10113d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips fLocation.fY - SkIntToScalar(y), 10128be952ad8c9deefe19cff36f9ad217563400f817Mike Reed fLocation.fZ - SkIntToScalar(z) * surfaceScale); 1013992c7612394a26e36ba355f6d8d3801d8d8f1260jvanverth fast_normalize(&direction); 1014f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org return direction; 1015fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein } 10160c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed SkPoint3 lightColor(const SkPoint3& surfaceToLight) const override { 1017f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar cosAngle = -surfaceToLight.dot(fS); 10183d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkScalar scale = 0; 10193d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips if (cosAngle >= fCosOuterConeAngle) { 10203d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips scale = SkScalarPow(cosAngle, fSpecularExponent); 10213d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips if (cosAngle < fCosInnerConeAngle) { 10228be952ad8c9deefe19cff36f9ad217563400f817Mike Reed scale *= (cosAngle - fCosOuterConeAngle) * fConeScale; 10233d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips } 1024f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 10253d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips return this->color().makeScale(scale); 1026f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 102736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrGLLight* createGLLight() const override { 1028cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 1029385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new GrGLSpotLight; 1030cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else 1031cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com SkDEBUGFAIL("Should not call in GPU-less build"); 103296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1033cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 1034894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org } 103536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein LightType type() const override { return kSpot_LightType; } 1036894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org const SkPoint3& location() const { return fLocation; } 1037894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org const SkPoint3& target() const { return fTarget; } 1038894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar specularExponent() const { return fSpecularExponent; } 1039894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar cosInnerConeAngle() const { return fCosInnerConeAngle; } 1040894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar cosOuterConeAngle() const { return fCosOuterConeAngle; } 1041894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkScalar coneScale() const { return fConeScale; } 1042eb311845c1b412a9a7d851444a70ec24ab60fb2csenorblanco@chromium.org const SkPoint3& s() const { return fS; } 10430833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com 10448b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkSpotLight(SkReadBuffer& buffer) : INHERITED(buffer) { 1045959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips fLocation = read_point3(buffer); 1046959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips fTarget = read_point3(buffer); 10470833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com fSpecularExponent = buffer.readScalar(); 10480833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com fCosOuterConeAngle = buffer.readScalar(); 10490833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com fCosInnerConeAngle = buffer.readScalar(); 10500833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com fConeScale = buffer.readScalar(); 1051959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips fS = read_point3(buffer); 1052c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org buffer.validate(SkScalarIsFinite(fSpecularExponent) && 1053c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org SkScalarIsFinite(fCosOuterConeAngle) && 1054c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org SkScalarIsFinite(fCosInnerConeAngle) && 1055c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org SkScalarIsFinite(fConeScale)); 10560833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com } 1057790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.orgprotected: 1058d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkSpotLight(const SkPoint3& location, 1059d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkPoint3& target, 1060d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar specularExponent, 1061d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar cosOuterConeAngle, 1062d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar cosInnerConeAngle, 1063d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar coneScale, 1064d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkPoint3& s, 1065d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkPoint3& color) 1066fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org : INHERITED(color), 1067fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org fLocation(location), 1068fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org fTarget(target), 1069fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org fSpecularExponent(specularExponent), 1070fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org fCosOuterConeAngle(cosOuterConeAngle), 1071fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org fCosInnerConeAngle(cosInnerConeAngle), 1072fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org fConeScale(coneScale), 1073fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org fS(s) 1074fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org { 1075fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org } 107636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onFlattenLight(SkWriteBuffer& buffer) const override { 1077959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips write_point3(fLocation, buffer); 1078959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips write_point3(fTarget, buffer); 10790833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com buffer.writeScalar(fSpecularExponent); 10800833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com buffer.writeScalar(fCosOuterConeAngle); 10810833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com buffer.writeScalar(fCosInnerConeAngle); 10820833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com buffer.writeScalar(fConeScale); 1083959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips write_point3(fS, buffer); 10840833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com } 10850833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com 10862f0dbc761a626473c19db7de561c7072b12953c5robertphillips bool isEqual(const SkImageFilterLight& other) const override { 1087894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org if (other.type() != kSpot_LightType) { 1088894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org return false; 1089894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org } 1090894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1091894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org const SkSpotLight& o = static_cast<const SkSpotLight&>(other); 1092894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org return INHERITED::isEqual(other) && 1093894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org fLocation == o.fLocation && 1094894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org fTarget == o.fTarget && 1095894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org fSpecularExponent == o.fSpecularExponent && 1096894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org fCosOuterConeAngle == o.fCosOuterConeAngle; 1097894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org } 1098894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1099f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.orgprivate: 11000bccd8749bdce79b2d71518fe65783b1a9b06445caryclark static const SkScalar kSpecularExponentMin; 11010bccd8749bdce79b2d71518fe65783b1a9b06445caryclark static const SkScalar kSpecularExponentMax; 11020bccd8749bdce79b2d71518fe65783b1a9b06445caryclark 1103f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkPoint3 fLocation; 1104f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkPoint3 fTarget; 1105f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar fSpecularExponent; 110662745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett SkScalar fCutoffAngle; 1107f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar fCosOuterConeAngle; 1108f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar fCosInnerConeAngle; 1109f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkScalar fConeScale; 1110f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SkPoint3 fS; 11112f0dbc761a626473c19db7de561c7072b12953c5robertphillips 11122f0dbc761a626473c19db7de561c7072b12953c5robertphillips typedef SkImageFilterLight INHERITED; 1113f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org}; 1114f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 11150bccd8749bdce79b2d71518fe65783b1a9b06445caryclark// According to the spec, the specular term should be in the range [1, 128] : 11160bccd8749bdce79b2d71518fe65783b1a9b06445caryclark// http://www.w3.org/TR/SVG/filters.html#feSpecularLightingSpecularExponentAttribute 11170bccd8749bdce79b2d71518fe65783b1a9b06445caryclarkconst SkScalar SkSpotLight::kSpecularExponentMin = 1.0f; 11180bccd8749bdce79b2d71518fe65783b1a9b06445caryclarkconst SkScalar SkSpotLight::kSpecularExponentMax = 128.0f; 11190bccd8749bdce79b2d71518fe65783b1a9b06445caryclark 1120894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1121894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 11222f0dbc761a626473c19db7de561c7072b12953c5robertphillipsvoid SkImageFilterLight::flattenLight(SkWriteBuffer& buffer) const { 1123790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org // Write type first, then baseclass, then subclass. 1124790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org buffer.writeInt(this->type()); 1125959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips write_point3(fColor, buffer); 1126790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org this->onFlattenLight(buffer); 1127790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org} 1128790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org 11292f0dbc761a626473c19db7de561c7072b12953c5robertphillips/*static*/ SkImageFilterLight* SkImageFilterLight::UnflattenLight(SkReadBuffer& buffer) { 1130de5c50268c3ff0af507c0a9b47ab58809b89867cMike Reed SkImageFilterLight::LightType type = buffer.read32LE(SkImageFilterLight::kLast_LightType); 1131959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips 1132790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org switch (type) { 1133790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org // Each of these constructors must first call SkLight's, so we'll read the baseclass 1134790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org // then subclass, same order as flattenLight. 1135385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary case SkImageFilterLight::kDistant_LightType: 1136385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkDistantLight(buffer); 1137385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary case SkImageFilterLight::kPoint_LightType: 1138385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkPointLight(buffer); 1139385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary case SkImageFilterLight::kSpot_LightType: 1140385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkSpotLight(buffer); 1141790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org default: 1142959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips // Should never get here due to prior check of SkSafeRange 1143790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org SkDEBUGFAIL("Unknown LightType."); 114496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1145790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org } 1146790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org} 1147790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 1148790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org 114912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipsSkLightingImageFilter::SkLightingImageFilter(sk_sp<SkImageFilterLight> light, 115012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, 115112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, const CropRect* cropRect) 115212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips : INHERITED(&input, 1, cropRect) 115312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips , fLight(std::move(light)) 115412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips , fSurfaceScale(surfaceScale / 255) { 1155f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1156f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 115782b043e87380a64ea4ca736b293ec0ee5c30e676robertphillipsSkLightingImageFilter::~SkLightingImageFilter() {} 115882b043e87380a64ea4ca736b293ec0ee5c30e676robertphillips 115912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipssk_sp<SkImageFilter> SkLightingImageFilter::MakeDistantLitDiffuse(const SkPoint3& direction, 116012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkColor lightColor, 116112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, 116212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar kd, 116312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 116412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const CropRect* cropRect) { 116512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilterLight> light(new SkDistantLight(direction, lightColor)); 1166fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein return SkDiffuseLightingImageFilter::Make(std::move(light), surfaceScale, kd, 116712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips std::move(input), cropRect); 1168f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1169f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 117012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipssk_sp<SkImageFilter> SkLightingImageFilter::MakePointLitDiffuse(const SkPoint3& location, 117112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkColor lightColor, 117212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, 117312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar kd, 117412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 117512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const CropRect* cropRect) { 117612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilterLight> light(new SkPointLight(location, lightColor)); 117712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips return SkDiffuseLightingImageFilter::Make(std::move(light), surfaceScale, kd, 117812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips std::move(input), cropRect); 1179f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1180f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 118112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipssk_sp<SkImageFilter> SkLightingImageFilter::MakeSpotLitDiffuse(const SkPoint3& location, 118212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const SkPoint3& target, 118312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar specularExponent, 118412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar cutoffAngle, 11859fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkColor lightColor, 11869fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar surfaceScale, 118712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar kd, 118812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 11899fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const CropRect* cropRect) { 119012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilterLight> light( 119112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips new SkSpotLight(location, target, specularExponent, cutoffAngle, lightColor)); 119212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips return SkDiffuseLightingImageFilter::Make(std::move(light), surfaceScale, kd, 119312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips std::move(input), cropRect); 1194f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1195f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 119612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipssk_sp<SkImageFilter> SkLightingImageFilter::MakeDistantLitSpecular(const SkPoint3& direction, 119712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkColor lightColor, 119812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, 119912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar ks, 120012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar shine, 120112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 120212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const CropRect* cropRect) { 120312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilterLight> light(new SkDistantLight(direction, lightColor)); 120412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips return SkSpecularLightingImageFilter::Make(std::move(light), surfaceScale, ks, shine, 120512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips std::move(input), cropRect); 1206f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1207f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 120812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipssk_sp<SkImageFilter> SkLightingImageFilter::MakePointLitSpecular(const SkPoint3& location, 120912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkColor lightColor, 121012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, 121112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar ks, 121212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar shine, 121312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 121412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const CropRect* cropRect) { 121512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilterLight> light(new SkPointLight(location, lightColor)); 121612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips return SkSpecularLightingImageFilter::Make(std::move(light), surfaceScale, ks, shine, 121712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips std::move(input), cropRect); 1218f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1219f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 122012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipssk_sp<SkImageFilter> SkLightingImageFilter::MakeSpotLitSpecular(const SkPoint3& location, 122112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const SkPoint3& target, 122212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar specularExponent, 122312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar cutoffAngle, 122412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkColor lightColor, 122512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, 122612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar ks, 122712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar shine, 122812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 122912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const CropRect* cropRect) { 123012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilterLight> light( 123112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips new SkSpotLight(location, target, specularExponent, cutoffAngle, lightColor)); 123212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips return SkSpecularLightingImageFilter::Make(std::move(light), surfaceScale, ks, shine, 123312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips std::move(input), cropRect); 123412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips} 1235f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 12368b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkLightingImageFilter::flatten(SkWriteBuffer& buffer) const { 1237f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org this->INHERITED::flatten(buffer); 1238790c3f4e095c57b1e2412a46e7d71f28babf07c8commit-bot@chromium.org fLight->flattenLight(buffer); 12399fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.writeScalar(fSurfaceScale * 255); 1240f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1241f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 12426b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomonsk_sp<const SkImageFilterLight> SkLightingImageFilter::refLight() const { return fLight; } 12436b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon 1244894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1245894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 124612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipssk_sp<SkImageFilter> SkDiffuseLightingImageFilter::Make(sk_sp<SkImageFilterLight> light, 124712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, 124812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar kd, 124912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 125012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const CropRect* cropRect) { 125112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips if (!light) { 125296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 12539fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 12549fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed if (!SkScalarIsFinite(surfaceScale) || !SkScalarIsFinite(kd)) { 125596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 12569fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 1257ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org // According to the spec, kd can be any non-negative number : 1258ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org // http://www.w3.org/TR/SVG/filters.html#feDiffuseLightingElement 12599fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed if (kd < 0) { 126096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 12619fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 1262fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein return sk_sp<SkImageFilter>(new SkDiffuseLightingImageFilter(std::move(light), surfaceScale, 126312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips kd, std::move(input), cropRect)); 12649fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 12659fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 126612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipsSkDiffuseLightingImageFilter::SkDiffuseLightingImageFilter(sk_sp<SkImageFilterLight> light, 1267d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar surfaceScale, 1268d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar kd, 126912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 1270d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const CropRect* cropRect) 127112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips : INHERITED(std::move(light), surfaceScale, std::move(input), cropRect) 127212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips , fKD(kd) { 1273f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1274f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 127560c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkDiffuseLightingImageFilter::CreateProc(SkReadBuffer& buffer) { 12769fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 1277959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips 127812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilterLight> light(SkImageFilterLight::UnflattenLight(buffer)); 12799fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar surfaceScale = buffer.readScalar(); 12809fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar kd = buffer.readScalar(); 1281959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips 128212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips return Make(std::move(light), surfaceScale, kd, common.getInput(0), &common.cropRect()); 12839fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 1284f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 12858b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkDiffuseLightingImageFilter::flatten(SkWriteBuffer& buffer) const { 1286f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org this->INHERITED::flatten(buffer); 1287f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org buffer.writeScalar(fKD); 1288f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1289f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 1290ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillipssk_sp<SkSpecialImage> SkDiffuseLightingImageFilter::onFilterImage(SkSpecialImage* source, 1291ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips const Context& ctx, 1292ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkIPoint* offset) const { 1293ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkIPoint inputOffset = SkIPoint::Make(0, 0); 1294ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset)); 1295ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (!input) { 1296ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1297a8aef8bf04b10ad648c448c16f56d8c487819112commit-bot@chromium.org } 1298a8aef8bf04b10ad648c448c16f56d8c487819112commit-bot@chromium.org 1299ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(), 1300ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips input->width(), input->height()); 1301118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkIRect bounds; 1302ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (!this->applyCropRect(ctx, inputBounds, &bounds)) { 1303ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1304ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips } 1305ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1306ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips offset->fX = bounds.left(); 1307ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips offset->fY = bounds.top(); 1308ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips bounds.offset(-inputOffset); 1309ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1310ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips#if SK_SUPPORT_GPU 1311ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (source->isTextureBacked()) { 1312ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkMatrix matrix(ctx.ctm()); 1313ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips matrix.postTranslate(SkIntToScalar(-offset->fX), SkIntToScalar(-offset->fY)); 1314ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 13152a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman return this->filterImageGPU(source, input.get(), bounds, matrix, ctx.outputProperties()); 1316f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 1317ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips#endif 13184e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org 1319118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (bounds.width() < 2 || bounds.height() < 2) { 1320ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1321ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips } 1322ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1323ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkBitmap inputBM; 1324ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1325ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (!input->getROPixels(&inputBM)) { 1326ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 13274e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org } 13284e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org 1329ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (inputBM.colorType() != kN32_SkColorType) { 1330ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1331ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips } 1332ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1333ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (!inputBM.getPixels()) { 1334ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1335f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 13364e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org 1337ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips const SkImageInfo info = SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()); 1338ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1339ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkBitmap dst; 1340ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (!dst.tryAllocPixels(info)) { 1341ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1342cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org } 1343ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 13447b7ecfc046f7ec810482266db3430d1358b7a5bfsenorblanco SkMatrix matrix(ctx.ctm()); 1345ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips matrix.postTranslate(SkIntToScalar(-inputOffset.x()), SkIntToScalar(-inputOffset.y())); 1346ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1347ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips sk_sp<SkImageFilterLight> transformedLight(light()->transform(matrix)); 1348fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org 1349f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org DiffuseLightingType lightingType(fKD); 13500c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed lightBitmap(lightingType, 1351ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips transformedLight.get(), 1352ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips inputBM, 1353ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips &dst, 1354d0d37cace08f12abf8d316e6949e947551d418e6senorblanco surfaceScale(), 1355d0d37cace08f12abf8d316e6949e947551d418e6senorblanco bounds); 13564e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org 13573e302275b324172c845627cbd00cee8a06571bafrobertphillips return SkSpecialImage::MakeFromRaster(SkIRect::MakeWH(bounds.width(), bounds.height()), 1358ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips dst); 1359f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1360f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 136162745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettsk_sp<SkImageFilter> SkDiffuseLightingImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) 136262745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettconst { 136362745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett SkASSERT(1 == this->countInputs()); 13646d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed auto input = xformer->apply(this->getInput(0)); 13656d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed auto light = this->light()->makeColorSpace(xformer); 13666d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed if (input.get() != this->getInput(0) || light.get() != this->light()) { 13676d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed return SkDiffuseLightingImageFilter::Make(std::move(light), 255.0f * this->surfaceScale(), 13686d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed fKD, std::move(input), this->getCropRectIfSet()); 13696d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed } 13706d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed return this->refMe(); 137162745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett} 137262745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett 1373f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#ifndef SK_IGNORE_TO_STRING 1374f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillipsvoid SkDiffuseLightingImageFilter::toString(SkString* str) const { 1375f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->appendf("SkDiffuseLightingImageFilter: ("); 1376f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->appendf("kD: %f\n", fKD); 1377f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->append(")"); 1378f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips} 1379f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#endif 1380f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips 1381cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 1382aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> SkDiffuseLightingImageFilter::makeFragmentProcessor( 1383aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon sk_sp<GrTextureProxy> proxy, 1384aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkMatrix& matrix, 1385aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkIRect* srcBounds, 1386aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon BoundaryMode boundaryMode) const { 13878be952ad8c9deefe19cff36f9ad217563400f817Mike Reed SkScalar scale = this->surfaceScale() * 255; 13886b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon return GrDiffuseLightingEffect::Make(std::move(proxy), this->refLight(), scale, matrix, 13896b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon this->kd(), boundaryMode, srcBounds); 1390894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1391d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#endif 1392894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1393894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1394894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 139512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipssk_sp<SkImageFilter> SkSpecularLightingImageFilter::Make(sk_sp<SkImageFilterLight> light, 139612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar surfaceScale, 139712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar ks, 139812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar shininess, 139912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 140012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const CropRect* cropRect) { 140112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips if (!light) { 140296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 14039fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 14049fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed if (!SkScalarIsFinite(surfaceScale) || !SkScalarIsFinite(ks) || !SkScalarIsFinite(shininess)) { 140596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 14069fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 1407ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org // According to the spec, ks can be any non-negative number : 1408ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org // http://www.w3.org/TR/SVG/filters.html#feSpecularLightingElement 14099fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed if (ks < 0) { 141096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 14119fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 141212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips return sk_sp<SkImageFilter>(new SkSpecularLightingImageFilter(std::move(light), surfaceScale, 141312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips ks, shininess, 141412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips std::move(input), cropRect)); 14159fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 14169fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 141712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillipsSkSpecularLightingImageFilter::SkSpecularLightingImageFilter(sk_sp<SkImageFilterLight> light, 1418d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar surfaceScale, 1419d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar ks, 1420d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar shininess, 142112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> input, 1422d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const CropRect* cropRect) 142312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips : INHERITED(std::move(light), surfaceScale, std::move(input), cropRect) 142412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips , fKS(ks) 142512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips , fShininess(shininess) { 1426f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1427f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 142860c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkSpecularLightingImageFilter::CreateProc(SkReadBuffer& buffer) { 14299fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 143012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilterLight> light(SkImageFilterLight::UnflattenLight(buffer)); 14319fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar surfaceScale = buffer.readScalar(); 14329fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar ks = buffer.readScalar(); 14339fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar shine = buffer.readScalar(); 1434959ccc2aefbaf0bc8b58f44d2fc85cddb1d027cfRobert Phillips 143512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips return Make(std::move(light), surfaceScale, ks, shine, common.getInput(0), 143612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips &common.cropRect()); 14379fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 1438f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 14398b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkSpecularLightingImageFilter::flatten(SkWriteBuffer& buffer) const { 1440f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org this->INHERITED::flatten(buffer); 1441f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org buffer.writeScalar(fKS); 1442f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org buffer.writeScalar(fShininess); 1443f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1444f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 1445ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillipssk_sp<SkSpecialImage> SkSpecularLightingImageFilter::onFilterImage(SkSpecialImage* source, 1446ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips const Context& ctx, 1447ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkIPoint* offset) const { 1448ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkIPoint inputOffset = SkIPoint::Make(0, 0); 1449ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset)); 1450ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (!input) { 1451ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1452a8aef8bf04b10ad648c448c16f56d8c487819112commit-bot@chromium.org } 1453a8aef8bf04b10ad648c448c16f56d8c487819112commit-bot@chromium.org 1454ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(), 1455ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips input->width(), input->height()); 1456ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkIRect bounds; 1457ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (!this->applyCropRect(ctx, inputBounds, &bounds)) { 1458ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1459f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 14604e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org 1461ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips offset->fX = bounds.left(); 1462ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips offset->fY = bounds.top(); 1463ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips bounds.offset(-inputOffset); 1464ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1465ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips#if SK_SUPPORT_GPU 1466ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (source->isTextureBacked()) { 1467ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkMatrix matrix(ctx.ctm()); 1468ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips matrix.postTranslate(SkIntToScalar(-offset->fX), SkIntToScalar(-offset->fY)); 1469ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 14702a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman return this->filterImageGPU(source, input.get(), bounds, matrix, ctx.outputProperties()); 1471f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org } 1472ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips#endif 14734e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org 147429089179a66c06ef70da387111af75970f04ed53senorblanco@chromium.org if (bounds.width() < 2 || bounds.height() < 2) { 1475ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1476ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips } 1477ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1478ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkBitmap inputBM; 1479ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1480ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (!input->getROPixels(&inputBM)) { 1481ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1482ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips } 1483ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1484ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (inputBM.colorType() != kN32_SkColorType) { 1485ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 14860ef0501baf615149d6d84398d7594cd89f6e928dsenorblanco@chromium.org } 14870ef0501baf615149d6d84398d7594cd89f6e928dsenorblanco@chromium.org 1488ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (!inputBM.getPixels()) { 1489ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1490118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org } 1491118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org 1492ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips const SkImageInfo info = SkImageInfo::MakeN32Premul(bounds.width(), bounds.height()); 1493ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1494ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips SkBitmap dst; 1495ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips if (!dst.tryAllocPixels(info)) { 1496ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips return nullptr; 1497cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org } 1498ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1499f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org SpecularLightingType lightingType(fKS, fShininess); 1500ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 15017b7ecfc046f7ec810482266db3430d1358b7a5bfsenorblanco SkMatrix matrix(ctx.ctm()); 1502ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips matrix.postTranslate(SkIntToScalar(-inputOffset.x()), SkIntToScalar(-inputOffset.y())); 1503ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 1504ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips sk_sp<SkImageFilterLight> transformedLight(light()->transform(matrix)); 1505ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 15060c182fc77e044edddb6606b7cf51b9a5b6c2eb54Mike Reed lightBitmap(lightingType, 1507ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips transformedLight.get(), 1508ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips inputBM, 1509ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips &dst, 1510d0d37cace08f12abf8d316e6949e947551d418e6senorblanco surfaceScale(), 1511d0d37cace08f12abf8d316e6949e947551d418e6senorblanco bounds); 1512ad3dc0da218cc43c9917a256d4afb8cf0d7c5899robertphillips 15133e302275b324172c845627cbd00cee8a06571bafrobertphillips return SkSpecialImage::MakeFromRaster(SkIRect::MakeWH(bounds.width(), bounds.height()), dst); 1514f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org} 1515f49b429ceface4f75f5f96570ea5a8b94896529dsenorblanco@chromium.org 151662745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettsk_sp<SkImageFilter> SkSpecularLightingImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) 151762745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettconst { 151862745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett SkASSERT(1 == this->countInputs()); 151962745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett 15206d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed auto input = xformer->apply(this->getInput(0)); 15216d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed auto light = this->light()->makeColorSpace(xformer); 15226d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed if (input.get() != this->getInput(0) || light.get() != this->light()) { 15236d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed return SkSpecularLightingImageFilter::Make(std::move(light), 15246d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed 255.0f * this->surfaceScale(), fKS, fShininess, 15256d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed std::move(input), this->getCropRectIfSet()); 15266d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed } 15276d9f42984d94a2e9116dd951d47cd65cd8f4d401Mike Reed return this->refMe(); 152862745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett} 152962745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett 1530f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#ifndef SK_IGNORE_TO_STRING 1531f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillipsvoid SkSpecularLightingImageFilter::toString(SkString* str) const { 1532f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->appendf("SkSpecularLightingImageFilter: ("); 1533f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->appendf("kS: %f shininess: %f", fKS, fShininess); 1534f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->append(")"); 1535f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips} 1536f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#endif 1537f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips 1538cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 1539aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> SkSpecularLightingImageFilter::makeFragmentProcessor( 1540aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon sk_sp<GrTextureProxy> proxy, 1541aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkMatrix& matrix, 1542aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon const SkIRect* srcBounds, 1543aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon BoundaryMode boundaryMode) const { 15448be952ad8c9deefe19cff36f9ad217563400f817Mike Reed SkScalar scale = this->surfaceScale() * 255; 15456b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon return GrSpecularLightingEffect::Make(std::move(proxy), this->refLight(), scale, matrix, 15466b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon this->ks(), this->shininess(), boundaryMode, srcBounds); 1547894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1548d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org#endif 1549894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1550894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1551894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1552cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 1553a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 155462745a8bba20d7ca91167915eb459339bcfb8862Matt Sarettstatic SkString emitNormalFunc(BoundaryMode mode, 155562745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett const char* pointToNormalName, 155662745a8bba20d7ca91167915eb459339bcfb8862Matt Sarett const char* sobelFuncName) { 1557d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkString result; 1558d0d37cace08f12abf8d316e6949e947551d418e6senorblanco switch (mode) { 1559d0d37cace08f12abf8d316e6949e947551d418e6senorblanco case kTopLeft_BoundaryMode: 1560d0d37cace08f12abf8d316e6949e947551d418e6senorblanco result.printf("\treturn %s(%s(0.0, 0.0, m[4], m[5], m[7], m[8], %g),\n" 1561d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t %s(0.0, 0.0, m[4], m[7], m[5], m[8], %g),\n" 1562d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t surfaceScale);\n", 1563d0d37cace08f12abf8d316e6949e947551d418e6senorblanco pointToNormalName, sobelFuncName, gTwoThirds, 1564d0d37cace08f12abf8d316e6949e947551d418e6senorblanco sobelFuncName, gTwoThirds); 1565d0d37cace08f12abf8d316e6949e947551d418e6senorblanco break; 1566d0d37cace08f12abf8d316e6949e947551d418e6senorblanco case kTop_BoundaryMode: 1567d0d37cace08f12abf8d316e6949e947551d418e6senorblanco result.printf("\treturn %s(%s(0.0, 0.0, m[3], m[5], m[6], m[8], %g),\n" 1568d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t %s(0.0, 0.0, m[4], m[7], m[5], m[8], %g),\n" 1569d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t surfaceScale);\n", 1570d0d37cace08f12abf8d316e6949e947551d418e6senorblanco pointToNormalName, sobelFuncName, gOneThird, 1571d0d37cace08f12abf8d316e6949e947551d418e6senorblanco sobelFuncName, gOneHalf); 1572d0d37cace08f12abf8d316e6949e947551d418e6senorblanco break; 1573d0d37cace08f12abf8d316e6949e947551d418e6senorblanco case kTopRight_BoundaryMode: 1574d0d37cace08f12abf8d316e6949e947551d418e6senorblanco result.printf("\treturn %s(%s( 0.0, 0.0, m[3], m[4], m[6], m[7], %g),\n" 1575d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t %s(m[3], m[6], m[4], m[7], 0.0, 0.0, %g),\n" 1576d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t surfaceScale);\n", 1577d0d37cace08f12abf8d316e6949e947551d418e6senorblanco pointToNormalName, sobelFuncName, gTwoThirds, 1578d0d37cace08f12abf8d316e6949e947551d418e6senorblanco sobelFuncName, gTwoThirds); 1579d0d37cace08f12abf8d316e6949e947551d418e6senorblanco break; 1580d0d37cace08f12abf8d316e6949e947551d418e6senorblanco case kLeft_BoundaryMode: 1581d0d37cace08f12abf8d316e6949e947551d418e6senorblanco result.printf("\treturn %s(%s(m[1], m[2], m[4], m[5], m[7], m[8], %g),\n" 1582d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t %s( 0.0, 0.0, m[1], m[7], m[2], m[8], %g),\n" 1583d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t surfaceScale);\n", 1584d0d37cace08f12abf8d316e6949e947551d418e6senorblanco pointToNormalName, sobelFuncName, gOneHalf, 1585d0d37cace08f12abf8d316e6949e947551d418e6senorblanco sobelFuncName, gOneThird); 1586d0d37cace08f12abf8d316e6949e947551d418e6senorblanco break; 1587d0d37cace08f12abf8d316e6949e947551d418e6senorblanco case kInterior_BoundaryMode: 1588d0d37cace08f12abf8d316e6949e947551d418e6senorblanco result.printf("\treturn %s(%s(m[0], m[2], m[3], m[5], m[6], m[8], %g),\n" 1589d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t %s(m[0], m[6], m[1], m[7], m[2], m[8], %g),\n" 1590d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t surfaceScale);\n", 1591d0d37cace08f12abf8d316e6949e947551d418e6senorblanco pointToNormalName, sobelFuncName, gOneQuarter, 1592d0d37cace08f12abf8d316e6949e947551d418e6senorblanco sobelFuncName, gOneQuarter); 1593d0d37cace08f12abf8d316e6949e947551d418e6senorblanco break; 1594d0d37cace08f12abf8d316e6949e947551d418e6senorblanco case kRight_BoundaryMode: 1595d0d37cace08f12abf8d316e6949e947551d418e6senorblanco result.printf("\treturn %s(%s(m[0], m[1], m[3], m[4], m[6], m[7], %g),\n" 1596d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t %s(m[0], m[6], m[1], m[7], 0.0, 0.0, %g),\n" 1597d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t surfaceScale);\n", 1598d0d37cace08f12abf8d316e6949e947551d418e6senorblanco pointToNormalName, sobelFuncName, gOneHalf, 1599d0d37cace08f12abf8d316e6949e947551d418e6senorblanco sobelFuncName, gOneThird); 1600d0d37cace08f12abf8d316e6949e947551d418e6senorblanco break; 1601d0d37cace08f12abf8d316e6949e947551d418e6senorblanco case kBottomLeft_BoundaryMode: 1602d0d37cace08f12abf8d316e6949e947551d418e6senorblanco result.printf("\treturn %s(%s(m[1], m[2], m[4], m[5], 0.0, 0.0, %g),\n" 1603d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t %s( 0.0, 0.0, m[1], m[4], m[2], m[5], %g),\n" 1604d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t surfaceScale);\n", 1605d0d37cace08f12abf8d316e6949e947551d418e6senorblanco pointToNormalName, sobelFuncName, gTwoThirds, 1606d0d37cace08f12abf8d316e6949e947551d418e6senorblanco sobelFuncName, gTwoThirds); 1607d0d37cace08f12abf8d316e6949e947551d418e6senorblanco break; 1608d0d37cace08f12abf8d316e6949e947551d418e6senorblanco case kBottom_BoundaryMode: 1609d0d37cace08f12abf8d316e6949e947551d418e6senorblanco result.printf("\treturn %s(%s(m[0], m[2], m[3], m[5], 0.0, 0.0, %g),\n" 1610d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t %s(m[0], m[3], m[1], m[4], m[2], m[5], %g),\n" 1611d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t surfaceScale);\n", 1612d0d37cace08f12abf8d316e6949e947551d418e6senorblanco pointToNormalName, sobelFuncName, gOneThird, 1613d0d37cace08f12abf8d316e6949e947551d418e6senorblanco sobelFuncName, gOneHalf); 1614d0d37cace08f12abf8d316e6949e947551d418e6senorblanco break; 1615d0d37cace08f12abf8d316e6949e947551d418e6senorblanco case kBottomRight_BoundaryMode: 1616d0d37cace08f12abf8d316e6949e947551d418e6senorblanco result.printf("\treturn %s(%s(m[0], m[1], m[3], m[4], 0.0, 0.0, %g),\n" 1617d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t %s(m[0], m[3], m[1], m[4], 0.0, 0.0, %g),\n" 1618d0d37cace08f12abf8d316e6949e947551d418e6senorblanco "\t surfaceScale);\n", 1619d0d37cace08f12abf8d316e6949e947551d418e6senorblanco pointToNormalName, sobelFuncName, gTwoThirds, 1620d0d37cace08f12abf8d316e6949e947551d418e6senorblanco sobelFuncName, gTwoThirds); 1621d0d37cace08f12abf8d316e6949e947551d418e6senorblanco break; 1622d0d37cace08f12abf8d316e6949e947551d418e6senorblanco default: 1623d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkASSERT(false); 1624d0d37cace08f12abf8d316e6949e947551d418e6senorblanco break; 1625d0d37cace08f12abf8d316e6949e947551d418e6senorblanco } 1626d0d37cace08f12abf8d316e6949e947551d418e6senorblanco return result; 1627d0d37cace08f12abf8d316e6949e947551d418e6senorblanco} 1628d0d37cace08f12abf8d316e6949e947551d418e6senorblanco 1629587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomonclass GrGLLightingEffect : public GrGLSLFragmentProcessor { 1630894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgpublic: 1631d3b32bf8322877cf263229735aef4f04df5415c4robertphillips GrGLLightingEffect() : fLight(nullptr) { } 1632d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon ~GrGLLightingEffect() override { delete fLight; } 1633894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 16347c157a988845fb00f9024d6db6dda142c3458033wangyix void emitCode(EmitArgs&) override; 1635894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 163694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon static inline void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b); 1637894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1638b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyixprotected: 1639ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com /** 1640b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix * Subclasses of GrGLLightingEffect must call INHERITED::onSetData(); 1641ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com */ 1642ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override; 1643894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 16447ea439b2203855db97330b25945b87dd4b170b8begdaniel virtual void emitLightFunc(GrGLSLUniformHandler*, 16458528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder*, 16467ea439b2203855db97330b25945b87dd4b170b8begdaniel SkString* funcName) = 0; 1647ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 1648894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgprivate: 164964c4728c70001ed074fecf5c4e083781987b12e9egdaniel typedef GrGLSLFragmentProcessor INHERITED; 1650894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 16519bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco UniformHandle fImageIncrementUni; 16529bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco UniformHandle fSurfaceScaleUni; 16539bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco GrTextureDomain::GLDomain fDomain; 16549bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco GrGLLight* fLight; 1655894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org}; 1656894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1657894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1658894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1659894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgclass GrGLDiffuseLightingEffect : public GrGLLightingEffect { 1660894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgpublic: 16618528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton void emitLightFunc(GrGLSLUniformHandler*, GrGLSLFPFragmentBuilder*, SkString* funcName) override; 1662b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix 1663b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyixprotected: 1664ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override; 1665894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1666894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgprivate: 1667894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org typedef GrGLLightingEffect INHERITED; 1668894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1669032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fKDUni; 1670894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org}; 1671894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1672894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1673894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1674894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgclass GrGLSpecularLightingEffect : public GrGLLightingEffect { 1675894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgpublic: 16768528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton void emitLightFunc(GrGLSLUniformHandler*, GrGLSLFPFragmentBuilder*, SkString* funcName) override; 1677b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix 1678b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyixprotected: 1679ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override; 1680894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1681894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.orgprivate: 1682894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org typedef GrGLLightingEffect INHERITED; 1683894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1684032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fKSUni; 1685032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle fShininessUni; 1686894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org}; 1687894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1688894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1689894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 16908e1c4e672553ecae2745168514240705f3516773Robert Phillipsstatic GrTextureDomain create_domain(GrTextureProxy* proxy, const SkIRect* srcBounds, 1691e98234f231d66848e149db683c11b6388e10b233Robert Phillips GrTextureDomain::Mode mode) { 16929bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco if (srcBounds) { 1693e98234f231d66848e149db683c11b6388e10b233Robert Phillips SkRect texelDomain = GrTextureDomain::MakeTexelDomainForMode(*srcBounds, mode); 16948e1c4e672553ecae2745168514240705f3516773Robert Phillips return GrTextureDomain(proxy, texelDomain, mode); 16959bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco } else { 1696e98234f231d66848e149db683c11b6388e10b233Robert Phillips return GrTextureDomain::IgnoredDomain(); 16979bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco } 16989bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco} 16999bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco 1700abff956455637b12eab374fd44b99e1338799113Ethan NicholasGrLightingEffect::GrLightingEffect(ClassID classID, 1701abff956455637b12eab374fd44b99e1338799113Ethan Nicholas sk_sp<GrTextureProxy> proxy, 17026b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon sk_sp<const SkImageFilterLight> light, 17034e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkScalar surfaceScale, 1704d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const SkMatrix& matrix, 17059bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco BoundaryMode boundaryMode, 17069bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco const SkIRect* srcBounds) 1707f3b995b628ef76bff28b9721dd1e182336156086Brian Salomon // Perhaps this could advertise the opaque or coverage-as-alpha optimizations? 1708abff956455637b12eab374fd44b99e1338799113Ethan Nicholas : INHERITED(classID, kNone_OptimizationFlags) 17096cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon , fCoordTransform(proxy.get()) 17106cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon , fDomain(create_domain(proxy.get(), srcBounds, GrTextureDomain::kDecal_Mode)) 17116cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon , fTextureSampler(std::move(proxy)) 17126b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon , fLight(std::move(light)) 1713587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon , fSurfaceScale(surfaceScale) 1714587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon , fFilterMatrix(matrix) 17156cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon , fBoundaryMode(boundaryMode) { 17166cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon this->addCoordTransform(&fCoordTransform); 17176cd51b51d6603a3100b147c45f38697f2f199fc6Brian Salomon this->addTextureSampler(&fTextureSampler); 1718894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1719894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 17206b17ff664ea8ead5a5d3e83436772dd0286603f5Brian SalomonGrLightingEffect::GrLightingEffect(const GrLightingEffect& that) 1721abff956455637b12eab374fd44b99e1338799113Ethan Nicholas : INHERITED(that.classID(), that.optimizationFlags()) 17226b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon , fCoordTransform(that.fCoordTransform) 17236b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon , fDomain(that.fDomain) 17246b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon , fTextureSampler(that.fTextureSampler) 17256b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon , fLight(that.fLight) 17266b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon , fSurfaceScale(that.fSurfaceScale) 17276b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon , fFilterMatrix(that.fFilterMatrix) 17286b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon , fBoundaryMode(that.fBoundaryMode) { 17296b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon this->addCoordTransform(&fCoordTransform); 17306b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon this->addTextureSampler(&fTextureSampler); 1731894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1732894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 17330e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrLightingEffect::onIsEqual(const GrFragmentProcessor& sBase) const { 173449586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrLightingEffect& s = sBase.cast<GrLightingEffect>(); 1735420d7e9a79358908850c74192b4949375563449absalomon return fLight->isEqual(*s.fLight) && 1736d0d37cace08f12abf8d316e6949e947551d418e6senorblanco fSurfaceScale == s.fSurfaceScale && 1737d0d37cace08f12abf8d316e6949e947551d418e6senorblanco fBoundaryMode == s.fBoundaryMode; 1738894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1739894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1740894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1741894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1742fbcef6eb8abad142daf45418516550f7635b4a52Robert PhillipsGrDiffuseLightingEffect::GrDiffuseLightingEffect(sk_sp<GrTextureProxy> proxy, 17436b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon sk_sp<const SkImageFilterLight>light, 17444e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkScalar surfaceScale, 1745fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org const SkMatrix& matrix, 1746d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar kd, 17479bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco BoundaryMode boundaryMode, 17489bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco const SkIRect* srcBounds) 1749abff956455637b12eab374fd44b99e1338799113Ethan Nicholas : INHERITED(kGrDiffuseLightingEffect_ClassID, std::move(proxy), std::move(light), 1750abff956455637b12eab374fd44b99e1338799113Ethan Nicholas surfaceScale, matrix, boundaryMode, srcBounds) 1751abff956455637b12eab374fd44b99e1338799113Ethan Nicholas , fKD(kd) {} 17526b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon 17536b17ff664ea8ead5a5d3e83436772dd0286603f5Brian SalomonGrDiffuseLightingEffect::GrDiffuseLightingEffect(const GrDiffuseLightingEffect& that) 1754abff956455637b12eab374fd44b99e1338799113Ethan Nicholas : INHERITED(that), fKD(that.fKD) {} 1755894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 17560e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrDiffuseLightingEffect::onIsEqual(const GrFragmentProcessor& sBase) const { 175749586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrDiffuseLightingEffect& s = sBase.cast<GrDiffuseLightingEffect>(); 1758d3b32bf8322877cf263229735aef4f04df5415c4robertphillips return INHERITED::onIsEqual(sBase) && this->kd() == s.kd(); 1759894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1760894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 176194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomonvoid GrDiffuseLightingEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, 176257d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrProcessorKeyBuilder* b) const { 1763eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLDiffuseLightingEffect::GenKey(*this, caps, b); 1764eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 1765eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 176657d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* GrDiffuseLightingEffect::onCreateGLSLInstance() const { 1767d3b32bf8322877cf263229735aef4f04df5415c4robertphillips return new GrGLDiffuseLightingEffect; 1768eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 1769eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 1770b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDiffuseLightingEffect); 1771a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 17726f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS 17730c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon 17740c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomonstatic SkPoint3 random_point3(SkRandom* random) { 17750c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon return SkPoint3::Make(SkScalarToFloat(random->nextSScalar1()), 17760c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon SkScalarToFloat(random->nextSScalar1()), 17770c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon SkScalarToFloat(random->nextSScalar1())); 17780c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon} 17790c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon 17800c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomonstatic SkImageFilterLight* create_random_light(SkRandom* random) { 17810c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon int type = random->nextULessThan(3); 17820c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon switch (type) { 17830c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon case 0: { 17840c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon return new SkDistantLight(random_point3(random), random->nextU()); 17850c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon } 17860c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon case 1: { 17870c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon return new SkPointLight(random_point3(random), random->nextU()); 17880c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon } 17890c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon case 2: { 17900c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon return new SkSpotLight(random_point3(random), random_point3(random), 17910c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon random->nextUScalar1(), random->nextUScalar1(), random->nextU()); 17920c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon } 17930c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon default: 1794b4aab9ae6d27c446af8302b79d15b832c816c633Ben Wagner SK_ABORT("Unexpected value."); 17950c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon return nullptr; 17960c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon } 17970c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon} 17980c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon 1799aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> GrDiffuseLightingEffect::TestCreate(GrProcessorTestData* d) { 18008e1c4e672553ecae2745168514240705f3516773Robert Phillips int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx 18018e1c4e672553ecae2745168514240705f3516773Robert Phillips : GrProcessorUnitTest::kAlphaTextureIdx; 18028e1c4e672553ecae2745168514240705f3516773Robert Phillips sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx); 18030067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt SkScalar surfaceScale = d->fRandom->nextSScalar1(); 18040067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt SkScalar kd = d->fRandom->nextUScalar1(); 180567b39de70fb5d10caebfc75f418754186e5226c3Hal Canary sk_sp<SkImageFilterLight> light(create_random_light(d->fRandom)); 1806fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix; 1807fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org for (int i = 0; i < 9; i++) { 18080067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt matrix[i] = d->fRandom->nextUScalar1(); 1809fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org } 18108e1c4e672553ecae2745168514240705f3516773Robert Phillips SkIRect srcBounds = SkIRect::MakeXYWH(d->fRandom->nextRangeU(0, proxy->width()), 18118e1c4e672553ecae2745168514240705f3516773Robert Phillips d->fRandom->nextRangeU(0, proxy->height()), 18128e1c4e672553ecae2745168514240705f3516773Robert Phillips d->fRandom->nextRangeU(0, proxy->width()), 18138e1c4e672553ecae2745168514240705f3516773Robert Phillips d->fRandom->nextRangeU(0, proxy->height())); 18140067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt BoundaryMode mode = static_cast<BoundaryMode>(d->fRandom->nextU() % kBoundaryModeCount); 18156b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon return GrDiffuseLightingEffect::Make(std::move(proxy), std::move(light), surfaceScale, matrix, 18166b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon kd, mode, &srcBounds); 1817a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com} 18186f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif 1819a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 1820a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 1821894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1822894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 18237c157a988845fb00f9024d6db6dda142c3458033wangyixvoid GrGLLightingEffect::emitCode(EmitArgs& args) { 1824d3b32bf8322877cf263229735aef4f04df5415c4robertphillips const GrLightingEffect& le = args.fFp.cast<GrLightingEffect>(); 1825d3b32bf8322877cf263229735aef4f04df5415c4robertphillips if (!fLight) { 1826d3b32bf8322877cf263229735aef4f04df5415c4robertphillips fLight = le.light()->createGLLight(); 1827d3b32bf8322877cf263229735aef4f04df5415c4robertphillips } 1828d3b32bf8322877cf263229735aef4f04df5415c4robertphillips 18297ea439b2203855db97330b25945b87dd4b170b8begdaniel GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 18305e58ceea8569f0d90ff7e3daf5de2def50407212cdalton fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 1831f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas kHalf2_GrSLType, "ImageIncrement"); 18325e58ceea8569f0d90ff7e3daf5de2def50407212cdalton fSurfaceScaleUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 1833f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas kHalf_GrSLType, "SurfaceScale"); 18347ea439b2203855db97330b25945b87dd4b170b8begdaniel fLight->emitLightColorUniform(uniformHandler); 18358528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 1836a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com SkString lightFunc; 18377ea439b2203855db97330b25945b87dd4b170b8begdaniel this->emitLightFunc(uniformHandler, fragBuilder, &lightFunc); 183899938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon static const GrShaderVar gSobelArgs[] = { 1839f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("a", kHalf_GrSLType), 1840f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("b", kHalf_GrSLType), 1841f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("c", kHalf_GrSLType), 1842f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("d", kHalf_GrSLType), 1843f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("e", kHalf_GrSLType), 1844f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("f", kHalf_GrSLType), 1845f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("scale", kHalf_GrSLType), 1846a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com }; 1847a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com SkString sobelFuncName; 18481a1aa9303484106a955e5549bf8ae24950f54e7absalomon SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); 18494ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel 1850f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->emitFunction(kHalf_GrSLType, 18514ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel "sobel", 18524ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel SK_ARRAY_COUNT(gSobelArgs), 18534ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gSobelArgs, 18544ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel "\treturn (-a + b - 2.0 * c + 2.0 * d -e + f) * scale;\n", 18554ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel &sobelFuncName); 185699938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon static const GrShaderVar gPointToNormalArgs[] = { 1857f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("x", kHalf_GrSLType), 1858f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("y", kHalf_GrSLType), 1859f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("scale", kHalf_GrSLType), 1860a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com }; 1861a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com SkString pointToNormalName; 1862f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->emitFunction(kHalf3_GrSLType, 18634ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel "pointToNormal", 18644ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel SK_ARRAY_COUNT(gPointToNormalArgs), 18654ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gPointToNormalArgs, 1866f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas "\treturn normalize(half3(-x * scale, -y * scale, 1));\n", 18674ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel &pointToNormalName); 1868a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 186999938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon static const GrShaderVar gInteriorNormalArgs[] = { 1870f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("m", kHalf_GrSLType, 9), 1871f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("surfaceScale", kHalf_GrSLType), 1872a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com }; 1873d3b32bf8322877cf263229735aef4f04df5415c4robertphillips SkString normalBody = emitNormalFunc(le.boundaryMode(), 1874d0d37cace08f12abf8d316e6949e947551d418e6senorblanco pointToNormalName.c_str(), 1875d0d37cace08f12abf8d316e6949e947551d418e6senorblanco sobelFuncName.c_str()); 1876d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkString normalName; 1877f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->emitFunction(kHalf3_GrSLType, 18784ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel "normal", 18794ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel SK_ARRAY_COUNT(gInteriorNormalArgs), 18804ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gInteriorNormalArgs, 18814ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel normalBody.c_str(), 18824ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel &normalName); 1883894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 18848aa4569c139a7a7ac38c62b25e3af40309cc2ee2Ethan Nicholas fragBuilder->codeAppendf("\t\tfloat2 coord = %s;\n", coords2D.c_str()); 1885f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->codeAppend("\t\thalf m[9];\n"); 1886032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com 18877ea439b2203855db97330b25945b87dd4b170b8begdaniel const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni); 18887ea439b2203855db97330b25945b87dd4b170b8begdaniel const char* surfScale = uniformHandler->getUniformCStr(fSurfaceScaleUni); 1889032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com 1890894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org int index = 0; 1891d0d37cace08f12abf8d316e6949e947551d418e6senorblanco for (int dy = 1; dy >= -1; dy--) { 1892894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org for (int dx = -1; dx <= 1; dx++) { 1893894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkString texCoords; 1894f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas texCoords.appendf("coord + half2(%d, %d) * %s", dx, dy, imgInc); 18959bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco SkString temp; 18969bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco temp.appendf("temp%d", index); 1897f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->codeAppendf("half4 %s;", temp.c_str()); 18989bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco fDomain.sampleTexture(fragBuilder, 18999bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco args.fUniformHandler, 19001edc5b92fecefb79f01cf0e302646eacf32b06c7Brian Salomon args.fShaderCaps, 19019bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco le.domain(), 19029bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco temp.c_str(), 19039bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco texCoords, 19043f6f76f98b6b37d17d1492791ff0feb1b7586bd6cdalton args.fTexSamplers[0]); 19059bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco fragBuilder->codeAppendf("m[%d] = %s.a;", index, temp.c_str()); 19069bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco index++; 1907894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org } 1908894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org } 1909f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->codeAppend("\t\thalf3 surfaceToLight = "); 1910894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org SkString arg; 1911032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com arg.appendf("%s * m[4]", surfScale); 19127ea439b2203855db97330b25945b87dd4b170b8begdaniel fLight->emitSurfaceToLight(uniformHandler, fragBuilder, arg.c_str()); 19134ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend(";\n"); 19144ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("\t\t%s = %s(%s(m, %s), surfaceToLight, ", 19154ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel args.fOutputColor, lightFunc.c_str(), normalName.c_str(), surfScale); 19167ea439b2203855db97330b25945b87dd4b170b8begdaniel fLight->emitLightColor(uniformHandler, fragBuilder, "surfaceToLight"); 19174ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend(");\n"); 19182983f4022d756def4f93579ee519cd31c8f24d61Ethan Nicholas fragBuilder->codeAppendf("%s *= %s;\n", args.fOutputColor, args.fInputColor); 1919894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1920894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1921b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GrGLLightingEffect::GenKey(const GrProcessor& proc, 192294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon const GrShaderCaps& caps, GrProcessorKeyBuilder* b) { 1923d0d37cace08f12abf8d316e6949e947551d418e6senorblanco const GrLightingEffect& lighting = proc.cast<GrLightingEffect>(); 1924d0d37cace08f12abf8d316e6949e947551d418e6senorblanco b->add32(lighting.boundaryMode() << 2 | lighting.light()->type()); 19259bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco b->add32(GrTextureDomain::GLDomain::DomainKey(lighting.domain())); 1926894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1927894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1928018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GrGLLightingEffect::onSetData(const GrGLSLProgramDataManager& pdman, 1929ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon const GrFragmentProcessor& proc) { 1930b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrLightingEffect& lighting = proc.cast<GrLightingEffect>(); 1931d3b32bf8322877cf263229735aef4f04df5415c4robertphillips if (!fLight) { 1932d3b32bf8322877cf263229735aef4f04df5415c4robertphillips fLight = lighting.light()->createGLLight(); 1933d3b32bf8322877cf263229735aef4f04df5415c4robertphillips } 1934d3b32bf8322877cf263229735aef4f04df5415c4robertphillips 1935c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips GrTextureProxy* proxy = lighting.textureSampler(0).proxy(); 1936c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips GrTexture* texture = proxy->priv().peekTexture(); 19379bee2e5894bb8dd374392f238bc429e16f239583Robert Phillips 1938c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips float ySign = proxy->origin() == kTopLeft_GrSurfaceOrigin ? -1.0f : 1.0f; 19397510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set2f(fImageIncrementUni, 1.0f / texture->width(), ySign / texture->height()); 19407510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fSurfaceScaleUni, lighting.surfaceScale()); 194167b39de70fb5d10caebfc75f418754186e5226c3Hal Canary sk_sp<SkImageFilterLight> transformedLight( 194267b39de70fb5d10caebfc75f418754186e5226c3Hal Canary lighting.light()->transform(lighting.filterMatrix())); 1943c686ce39f06d556d55befd290e0eb82851c7d33bRobert Phillips fDomain.setData(pdman, lighting.domain(), proxy); 194467b39de70fb5d10caebfc75f418754186e5226c3Hal Canary fLight->setData(pdman, transformedLight.get()); 1945894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1946894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1947894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1948894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1949894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1950894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 19517ea439b2203855db97330b25945b87dd4b170b8begdanielvoid GrGLDiffuseLightingEffect::emitLightFunc(GrGLSLUniformHandler* uniformHandler, 19528528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder, 19534ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel SkString* funcName) { 1954ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* kd; 1955f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fKDUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "KD", &kd); 1956ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 195799938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon static const GrShaderVar gLightArgs[] = { 1958f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("normal", kHalf3_GrSLType), 1959f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("surfaceToLight", kHalf3_GrSLType), 1960f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("lightColor", kHalf3_GrSLType) 1961a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com }; 1962a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com SkString lightBody; 1963f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas lightBody.appendf("\thalf colorScale = %s * dot(normal, surfaceToLight);\n", kd); 1964f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas lightBody.appendf("\treturn half4(lightColor * clamp(colorScale, 0.0, 1.0), 1.0);\n"); 1965f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->emitFunction(kHalf4_GrSLType, 19664ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel "light", 19674ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel SK_ARRAY_COUNT(gLightArgs), 19684ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gLightArgs, 19694ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel lightBody.c_str(), 19704ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel funcName); 1971894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1972894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1973018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GrGLDiffuseLightingEffect::onSetData(const GrGLSLProgramDataManager& pdman, 1974ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon const GrFragmentProcessor& proc) { 1975b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix INHERITED::onSetData(pdman, proc); 1976b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDiffuseLightingEffect& diffuse = proc.cast<GrDiffuseLightingEffect>(); 19777510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fKDUni, diffuse.kd()); 1978894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 1979894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1980894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 1981894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 1982fbcef6eb8abad142daf45418516550f7635b4a52Robert PhillipsGrSpecularLightingEffect::GrSpecularLightingEffect(sk_sp<GrTextureProxy> proxy, 19836b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon sk_sp<const SkImageFilterLight> light, 19844e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkScalar surfaceScale, 1985fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org const SkMatrix& matrix, 19864e16bb2a322f2bd16cb1afd2f78c27e420a4b9dbsenorblanco@chromium.org SkScalar ks, 1987d0d37cace08f12abf8d316e6949e947551d418e6senorblanco SkScalar shininess, 19889bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco BoundaryMode boundaryMode, 19899bd5f746ca45ebec0ed3b54dcbd6cf5fc2754c3csenorblanco const SkIRect* srcBounds) 1990abff956455637b12eab374fd44b99e1338799113Ethan Nicholas : INHERITED(kGrSpecularLightingEffect_ClassID, std::move(proxy), std::move(light), 1991abff956455637b12eab374fd44b99e1338799113Ethan Nicholas surfaceScale, matrix, boundaryMode, srcBounds) 19926b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon , fKS(ks) 1993abff956455637b12eab374fd44b99e1338799113Ethan Nicholas , fShininess(shininess) {} 19946b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon 19956b17ff664ea8ead5a5d3e83436772dd0286603f5Brian SalomonGrSpecularLightingEffect::GrSpecularLightingEffect(const GrSpecularLightingEffect& that) 1996abff956455637b12eab374fd44b99e1338799113Ethan Nicholas : INHERITED(that), fKS(that.fKS), fShininess(that.fShininess) {} 1997894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 19980e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrSpecularLightingEffect::onIsEqual(const GrFragmentProcessor& sBase) const { 199949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrSpecularLightingEffect& s = sBase.cast<GrSpecularLightingEffect>(); 200068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com return INHERITED::onIsEqual(sBase) && 2001894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org this->ks() == s.ks() && 2002894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org this->shininess() == s.shininess(); 2003894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2004894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 200594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomonvoid GrSpecularLightingEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, 200657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrProcessorKeyBuilder* b) const { 2007eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLSpecularLightingEffect::GenKey(*this, caps, b); 2008eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 2009eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 201057d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* GrSpecularLightingEffect::onCreateGLSLInstance() const { 2011d3b32bf8322877cf263229735aef4f04df5415c4robertphillips return new GrGLSpecularLightingEffect; 2012eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 2013eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 2014b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSpecularLightingEffect); 2015a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 20166f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS 2017aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> GrSpecularLightingEffect::TestCreate(GrProcessorTestData* d) { 20188e1c4e672553ecae2745168514240705f3516773Robert Phillips int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx 20198e1c4e672553ecae2745168514240705f3516773Robert Phillips : GrProcessorUnitTest::kAlphaTextureIdx; 20208e1c4e672553ecae2745168514240705f3516773Robert Phillips sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx); 20210067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt SkScalar surfaceScale = d->fRandom->nextSScalar1(); 20220067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt SkScalar ks = d->fRandom->nextUScalar1(); 20230067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt SkScalar shininess = d->fRandom->nextUScalar1(); 202467b39de70fb5d10caebfc75f418754186e5226c3Hal Canary sk_sp<SkImageFilterLight> light(create_random_light(d->fRandom)); 2025fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix; 2026fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org for (int i = 0; i < 9; i++) { 20270067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt matrix[i] = d->fRandom->nextUScalar1(); 2028fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org } 20290067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt BoundaryMode mode = static_cast<BoundaryMode>(d->fRandom->nextU() % kBoundaryModeCount); 20308e1c4e672553ecae2745168514240705f3516773Robert Phillips SkIRect srcBounds = SkIRect::MakeXYWH(d->fRandom->nextRangeU(0, proxy->width()), 20318e1c4e672553ecae2745168514240705f3516773Robert Phillips d->fRandom->nextRangeU(0, proxy->height()), 20328e1c4e672553ecae2745168514240705f3516773Robert Phillips d->fRandom->nextRangeU(0, proxy->width()), 20338e1c4e672553ecae2745168514240705f3516773Robert Phillips d->fRandom->nextRangeU(0, proxy->height())); 20346b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon return GrSpecularLightingEffect::Make(std::move(proxy), std::move(light), surfaceScale, matrix, 20356b17ff664ea8ead5a5d3e83436772dd0286603f5Brian Salomon ks, shininess, mode, &srcBounds); 2036a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com} 20376f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif 2038a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 2039894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 2040894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 20417ea439b2203855db97330b25945b87dd4b170b8begdanielvoid GrGLSpecularLightingEffect::emitLightFunc(GrGLSLUniformHandler* uniformHandler, 20428528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder, 20434ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel SkString* funcName) { 2044ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* ks; 2045ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* shininess; 2046ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 2047f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fKSUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "KS", &ks); 20485e58ceea8569f0d90ff7e3daf5de2def50407212cdalton fShininessUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 2049f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas kHalf_GrSLType, 20507ea439b2203855db97330b25945b87dd4b170b8begdaniel "Shininess", 20517ea439b2203855db97330b25945b87dd4b170b8begdaniel &shininess); 2052a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 205399938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon static const GrShaderVar gLightArgs[] = { 2054f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("normal", kHalf3_GrSLType), 2055f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("surfaceToLight", kHalf3_GrSLType), 2056f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("lightColor", kHalf3_GrSLType) 2057a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com }; 2058a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com SkString lightBody; 2059f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas lightBody.appendf("\thalf3 halfDir = half3(normalize(surfaceToLight + half3(0, 0, 1)));\n"); 20608aa4569c139a7a7ac38c62b25e3af40309cc2ee2Ethan Nicholas lightBody.appendf("\tfloat colorScale = %s * pow(dot(normal, halfDir), %s);\n", 20619bc39bbd1a18d61e4e9c3808c33ea003a8e49938Brian Osman ks, shininess); 2062f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas lightBody.appendf("\thalf3 color = lightColor * clamp(colorScale, 0.0, 1.0);\n"); 2063f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas lightBody.appendf("\treturn half4(color, max(max(color.r, color.g), color.b));\n"); 2064f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->emitFunction(kHalf4_GrSLType, 20654ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel "light", 20664ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel SK_ARRAY_COUNT(gLightArgs), 20674ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gLightArgs, 20684ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel lightBody.c_str(), 20694ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel funcName); 2070894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2071894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 2072018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GrGLSpecularLightingEffect::onSetData(const GrGLSLProgramDataManager& pdman, 2073ab015efc48c462ffdffebb45c02cd19efb254983Brian Salomon const GrFragmentProcessor& effect) { 2074b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix INHERITED::onSetData(pdman, effect); 207549586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrSpecularLightingEffect& spec = effect.cast<GrSpecularLightingEffect>(); 20767510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fKSUni, spec.ks()); 20777510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fShininessUni, spec.shininess()); 2078894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2079894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 2080894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 20817ea439b2203855db97330b25945b87dd4b170b8begdanielvoid GrGLLight::emitLightColorUniform(GrGLSLUniformHandler* uniformHandler) { 2082f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf3_GrSLType, "LightColor"); 2083894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2084894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 20857ea439b2203855db97330b25945b87dd4b170b8begdanielvoid GrGLLight::emitLightColor(GrGLSLUniformHandler* uniformHandler, 20868528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder, 20874ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel const char *surfaceToLight) { 20887ea439b2203855db97330b25945b87dd4b170b8begdaniel fragBuilder->codeAppend(uniformHandler->getUniformCStr(this->lightColorUni())); 2089ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com} 2090ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 2091018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GrGLLight::setData(const GrGLSLProgramDataManager& pdman, 20922f0dbc761a626473c19db7de561c7072b12953c5robertphillips const SkImageFilterLight* light) const { 20933d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips setUniformPoint3(pdman, fColorUni, 20943d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips light->color().makeScale(SkScalarInvert(SkIntToScalar(255)))); 2095894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2096894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 2097894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 2098894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 2099018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GrGLDistantLight::setData(const GrGLSLProgramDataManager& pdman, 21002f0dbc761a626473c19db7de561c7072b12953c5robertphillips const SkImageFilterLight* light) const { 21017510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen INHERITED::setData(pdman, light); 21022f0dbc761a626473c19db7de561c7072b12953c5robertphillips SkASSERT(light->type() == SkImageFilterLight::kDistant_LightType); 2103894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org const SkDistantLight* distantLight = static_cast<const SkDistantLight*>(light); 21047510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen setUniformNormal3(pdman, fDirectionUni, distantLight->direction()); 2105894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2106894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 21077ea439b2203855db97330b25945b87dd4b170b8begdanielvoid GrGLDistantLight::emitSurfaceToLight(GrGLSLUniformHandler* uniformHandler, 21088528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder, 21094ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel const char* z) { 2110ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* dir; 2111f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fDirectionUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf3_GrSLType, 21127ea439b2203855db97330b25945b87dd4b170b8begdaniel "LightDirection", &dir); 21134ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend(dir); 2114894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2115894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 2116894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 2117894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 2118018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GrGLPointLight::setData(const GrGLSLProgramDataManager& pdman, 21192f0dbc761a626473c19db7de561c7072b12953c5robertphillips const SkImageFilterLight* light) const { 21207510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen INHERITED::setData(pdman, light); 21212f0dbc761a626473c19db7de561c7072b12953c5robertphillips SkASSERT(light->type() == SkImageFilterLight::kPoint_LightType); 2122894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org const SkPointLight* pointLight = static_cast<const SkPointLight*>(light); 21237510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen setUniformPoint3(pdman, fLocationUni, pointLight->location()); 2124894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2125894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 21267ea439b2203855db97330b25945b87dd4b170b8begdanielvoid GrGLPointLight::emitSurfaceToLight(GrGLSLUniformHandler* uniformHandler, 21278528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder, 21284ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel const char* z) { 2129ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* loc; 2130f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fLocationUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf3_GrSLType, 21317ea439b2203855db97330b25945b87dd4b170b8begdaniel "LightLocation", &loc); 2132f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->codeAppendf("normalize(%s - half3(sk_FragCoord.xy, %s))", 21333865711259e25a90a1d72480f848863ada202067Ethan Nicholas loc, z); 2134894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2135894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 2136894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 2137894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 2138018fb62d12d1febf121fe265da5b6117b86a6541egdanielvoid GrGLSpotLight::setData(const GrGLSLProgramDataManager& pdman, 21392f0dbc761a626473c19db7de561c7072b12953c5robertphillips const SkImageFilterLight* light) const { 21407510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen INHERITED::setData(pdman, light); 21412f0dbc761a626473c19db7de561c7072b12953c5robertphillips SkASSERT(light->type() == SkImageFilterLight::kSpot_LightType); 2142894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org const SkSpotLight* spotLight = static_cast<const SkSpotLight *>(light); 21437510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen setUniformPoint3(pdman, fLocationUni, spotLight->location()); 21447510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fExponentUni, spotLight->specularExponent()); 21457510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fCosInnerConeAngleUni, spotLight->cosInnerConeAngle()); 21467510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fCosOuterConeAngleUni, spotLight->cosOuterConeAngle()); 21477510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fConeScaleUni, spotLight->coneScale()); 21487510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen setUniformNormal3(pdman, fSUni, spotLight->s()); 2149894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2150894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 21517ea439b2203855db97330b25945b87dd4b170b8begdanielvoid GrGLSpotLight::emitSurfaceToLight(GrGLSLUniformHandler* uniformHandler, 21528528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder, 21534ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel const char* z) { 2154ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* location; 2155f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fLocationUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf3_GrSLType, 21567ea439b2203855db97330b25945b87dd4b170b8begdaniel "LightLocation", &location); 215730ba436f04e61d4505fb854d5fc56079636e0788joshualitt 2158f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->codeAppendf("normalize(%s - half3(sk_FragCoord.xy, %s))", 21593865711259e25a90a1d72480f848863ada202067Ethan Nicholas location, z); 2160894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2161894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 21627ea439b2203855db97330b25945b87dd4b170b8begdanielvoid GrGLSpotLight::emitLightColor(GrGLSLUniformHandler* uniformHandler, 21638528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder, 2164ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char *surfaceToLight) { 2165ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 21667ea439b2203855db97330b25945b87dd4b170b8begdaniel const char* color = uniformHandler->getUniformCStr(this->lightColorUni()); // created by parent class. 2167ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 2168ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* exponent; 2169ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* cosInner; 2170ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* cosOuter; 2171ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* coneScale; 2172ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com const char* s; 2173f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fExponentUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, 21747ea439b2203855db97330b25945b87dd4b170b8begdaniel "Exponent", &exponent); 2175f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fCosInnerConeAngleUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, 21767ea439b2203855db97330b25945b87dd4b170b8begdaniel "CosInnerConeAngle", &cosInner); 2177f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fCosOuterConeAngleUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, 21787ea439b2203855db97330b25945b87dd4b170b8begdaniel "CosOuterConeAngle", &cosOuter); 2179f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fConeScaleUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, 21807ea439b2203855db97330b25945b87dd4b170b8begdaniel "ConeScale", &coneScale); 2181f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fSUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf3_GrSLType, "S", &s); 2182ae5ef113ebd7f20f1bea952a0ed9bb6d47cbda92bsalomon@google.com 218399938a8ef24e2dd5b39f78638742e9b50ab6d9bfBrian Salomon static const GrShaderVar gLightColorArgs[] = { 2184f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas GrShaderVar("surfaceToLight", kHalf3_GrSLType) 2185a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com }; 2186a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com SkString lightColorBody; 2187f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas lightColorBody.appendf("\thalf cosAngle = -dot(surfaceToLight, %s);\n", s); 2188a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com lightColorBody.appendf("\tif (cosAngle < %s) {\n", cosOuter); 2189f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas lightColorBody.appendf("\t\treturn half3(0);\n"); 2190a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com lightColorBody.appendf("\t}\n"); 2191f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas lightColorBody.appendf("\thalf scale = pow(cosAngle, %s);\n", exponent); 2192a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com lightColorBody.appendf("\tif (cosAngle < %s) {\n", cosInner); 2193a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com lightColorBody.appendf("\t\treturn %s * scale * (cosAngle - %s) * %s;\n", 2194a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com color, cosOuter, coneScale); 2195a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com lightColorBody.appendf("\t}\n"); 21960bccd8749bdce79b2d71518fe65783b1a9b06445caryclark lightColorBody.appendf("\treturn %s;\n", color); 2197f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas fragBuilder->emitFunction(kHalf3_GrSLType, 21984ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel "lightColor", 21994ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel SK_ARRAY_COUNT(gLightColorArgs), 22004ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gLightColorArgs, 22014ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel lightColorBody.c_str(), 22024ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel &fLightColorFunc); 22034ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel 22044ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight); 2205894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org} 2206894790d77c56cd4bae8070331d275c6d2897e33csenorblanco@chromium.org 2207cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 2208cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 22090833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter) 22100833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter) 22110833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.com SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter) 22120833777df1f05adafd9b70c666a72d80defa4f6bdjsollen@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 2213