Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/effects/SkLightingImageFilter.cpp

Issue 1240023002: Add fast normalize for SkLightingImageFilter. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Address nits Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 The Android Open Source Project 2 * Copyright 2012 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkLightingImageFilter.h" 8 #include "SkLightingImageFilter.h"
9 #include "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 // Shift matrix components to the left, as we advance pixels to the right. 53 // Shift matrix components to the left, as we advance pixels to the right.
54 inline void shiftMatrixLeft(int m[9]) { 54 inline void shiftMatrixLeft(int m[9]) {
55 m[0] = m[1]; 55 m[0] = m[1];
56 m[3] = m[4]; 56 m[3] = m[4];
57 m[6] = m[7]; 57 m[6] = m[7];
58 m[1] = m[2]; 58 m[1] = m[2];
59 m[4] = m[5]; 59 m[4] = m[5];
60 m[7] = m[8]; 60 m[7] = m[8];
61 } 61 }
62 62
63 static inline void fast_normalize(SkPoint3* vector) {
64 // add a tiny bit so we don't have to worry about divide-by-zero
65 SkScalar magSq = vector->dot(*vector) + SK_ScalarNearlyZero;
66 SkScalar scale = sk_float_rsqrt(magSq);
67 vector->fX *= scale;
68 vector->fY *= scale;
69 vector->fZ *= scale;
70 }
71
63 class DiffuseLightingType { 72 class DiffuseLightingType {
64 public: 73 public:
65 DiffuseLightingType(SkScalar kd) 74 DiffuseLightingType(SkScalar kd)
66 : fKD(kd) {} 75 : fKD(kd) {}
67 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, 76 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight,
68 const SkPoint3& lightColor) const { 77 const SkPoint3& lightColor) const {
69 SkScalar colorScale = SkScalarMul(fKD, normal.dot(surfaceTolight)); 78 SkScalar colorScale = SkScalarMul(fKD, normal.dot(surfaceTolight));
70 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); 79 colorScale = SkScalarClampMax(colorScale, SK_Scalar1);
71 SkPoint3 color = lightColor.makeScale(colorScale); 80 SkPoint3 color = lightColor.makeScale(colorScale);
72 return SkPackARGB32(255, 81 return SkPackARGB32(255,
(...skipping 10 matching lines...) Expand all
83 } 92 }
84 93
85 class SpecularLightingType { 94 class SpecularLightingType {
86 public: 95 public:
87 SpecularLightingType(SkScalar ks, SkScalar shininess) 96 SpecularLightingType(SkScalar ks, SkScalar shininess)
88 : fKS(ks), fShininess(shininess) {} 97 : fKS(ks), fShininess(shininess) {}
89 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, 98 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight,
90 const SkPoint3& lightColor) const { 99 const SkPoint3& lightColor) const {
91 SkPoint3 halfDir(surfaceTolight); 100 SkPoint3 halfDir(surfaceTolight);
92 halfDir.fZ += SK_Scalar1; // eye position is always (0, 0, 1) 101 halfDir.fZ += SK_Scalar1; // eye position is always (0, 0, 1)
93 halfDir.normalize(); 102 fast_normalize(&halfDir);
94 SkScalar colorScale = SkScalarMul(fKS, 103 SkScalar colorScale = SkScalarMul(fKS,
95 SkScalarPow(normal.dot(halfDir), fShininess)); 104 SkScalarPow(normal.dot(halfDir), fShininess));
96 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); 105 colorScale = SkScalarClampMax(colorScale, SK_Scalar1);
97 SkPoint3 color = lightColor.makeScale(colorScale); 106 SkPoint3 color = lightColor.makeScale(colorScale);
98 return SkPackARGB32(SkClampMax(SkScalarRoundToInt(max_component(color)), 255), 107 return SkPackARGB32(SkClampMax(SkScalarRoundToInt(max_component(color)), 255),
99 SkClampMax(SkScalarRoundToInt(color.fX), 255), 108 SkClampMax(SkScalarRoundToInt(color.fX), 255),
100 SkClampMax(SkScalarRoundToInt(color.fY), 255), 109 SkClampMax(SkScalarRoundToInt(color.fY), 255),
101 SkClampMax(SkScalarRoundToInt(color.fZ), 255)); 110 SkClampMax(SkScalarRoundToInt(color.fZ), 255));
102 } 111 }
103 private: 112 private:
104 SkScalar fKS; 113 SkScalar fKS;
105 SkScalar fShininess; 114 SkScalar fShininess;
106 }; 115 };
107 116
108 inline SkScalar sobel(int a, int b, int c, int d, int e, int f, SkScalar scale) { 117 inline SkScalar sobel(int a, int b, int c, int d, int e, int f, SkScalar scale) {
109 return SkScalarMul(SkIntToScalar(-a + b - 2 * c + 2 * d -e + f), scale); 118 return SkScalarMul(SkIntToScalar(-a + b - 2 * c + 2 * d -e + f), scale);
110 } 119 }
111 120
112 inline SkPoint3 pointToNormal(SkScalar x, SkScalar y, SkScalar surfaceScale) { 121 inline SkPoint3 pointToNormal(SkScalar x, SkScalar y, SkScalar surfaceScale) {
113 SkPoint3 vector = SkPoint3::Make(SkScalarMul(-x, surfaceScale), 122 SkPoint3 vector = SkPoint3::Make(SkScalarMul(-x, surfaceScale),
114 SkScalarMul(-y, surfaceScale), 123 SkScalarMul(-y, surfaceScale),
115 SK_Scalar1); 124 SK_Scalar1);
116 vector.normalize(); 125 fast_normalize(&vector);
117 return vector; 126 return vector;
118 } 127 }
119 128
120 inline SkPoint3 topLeftNormal(int m[9], SkScalar surfaceScale) { 129 inline SkPoint3 topLeftNormal(int m[9], SkScalar surfaceScale) {
121 return pointToNormal(sobel(0, 0, m[4], m[5], m[7], m[8], gTwoThirds), 130 return pointToNormal(sobel(0, 0, m[4], m[5], m[7], m[8], gTwoThirds),
122 sobel(0, 0, m[4], m[7], m[5], m[8], gTwoThirds), 131 sobel(0, 0, m[4], m[7], m[5], m[8], gTwoThirds),
123 surfaceScale); 132 surfaceScale);
124 } 133 }
125 134
126 inline SkPoint3 topNormal(int m[9], SkScalar surfaceScale) { 135 inline SkPoint3 topNormal(int m[9], SkScalar surfaceScale) {
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 class SkPointLight : public SkLight { 802 class SkPointLight : public SkLight {
794 public: 803 public:
795 SkPointLight(const SkPoint3& location, SkColor color) 804 SkPointLight(const SkPoint3& location, SkColor color)
796 : INHERITED(color), fLocation(location) {} 805 : INHERITED(color), fLocation(location) {}
797 806
798 SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const { 807 SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const {
799 SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x), 808 SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x),
800 fLocation.fY - SkIntToScalar(y), 809 fLocation.fY - SkIntToScalar(y),
801 fLocation.fZ - SkScalarMul(SkIntToSc alar(z), 810 fLocation.fZ - SkScalarMul(SkIntToSc alar(z),
802 surfaceSc ale)); 811 surfaceSc ale));
803 direction.normalize(); 812 fast_normalize(&direction);
804 return direction; 813 return direction;
805 }; 814 };
806 const SkPoint3& lightColor(const SkPoint3&) const { return this->color(); } 815 const SkPoint3& lightColor(const SkPoint3&) const { return this->color(); }
807 LightType type() const override { return kPoint_LightType; } 816 LightType type() const override { return kPoint_LightType; }
808 const SkPoint3& location() const { return fLocation; } 817 const SkPoint3& location() const { return fLocation; }
809 GrGLLight* createGLLight() const override { 818 GrGLLight* createGLLight() const override {
810 #if SK_SUPPORT_GPU 819 #if SK_SUPPORT_GPU
811 return SkNEW(GrGLPointLight); 820 return SkNEW(GrGLPointLight);
812 #else 821 #else
813 SkDEBUGFAIL("Should not call in GPU-less build"); 822 SkDEBUGFAIL("Should not call in GPU-less build");
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 const SkPoint3& target, 868 const SkPoint3& target,
860 SkScalar specularExponent, 869 SkScalar specularExponent,
861 SkScalar cutoffAngle, 870 SkScalar cutoffAngle,
862 SkColor color) 871 SkColor color)
863 : INHERITED(color), 872 : INHERITED(color),
864 fLocation(location), 873 fLocation(location),
865 fTarget(target), 874 fTarget(target),
866 fSpecularExponent(SkScalarPin(specularExponent, kSpecularExponentMin, kSp ecularExponentMax)) 875 fSpecularExponent(SkScalarPin(specularExponent, kSpecularExponentMin, kSp ecularExponentMax))
867 { 876 {
868 fS = target - location; 877 fS = target - location;
869 fS.normalize(); 878 fast_normalize(&fS);
870 fCosOuterConeAngle = SkScalarCos(SkDegreesToRadians(cutoffAngle)); 879 fCosOuterConeAngle = SkScalarCos(SkDegreesToRadians(cutoffAngle));
871 const SkScalar antiAliasThreshold = 0.016f; 880 const SkScalar antiAliasThreshold = 0.016f;
872 fCosInnerConeAngle = fCosOuterConeAngle + antiAliasThreshold; 881 fCosInnerConeAngle = fCosOuterConeAngle + antiAliasThreshold;
873 fConeScale = SkScalarInvert(antiAliasThreshold); 882 fConeScale = SkScalarInvert(antiAliasThreshold);
874 } 883 }
875 884
876 SkLight* transform(const SkMatrix& matrix) const override { 885 SkLight* transform(const SkMatrix& matrix) const override {
877 SkPoint location2 = SkPoint::Make(fLocation.fX, fLocation.fY); 886 SkPoint location2 = SkPoint::Make(fLocation.fX, fLocation.fY);
878 matrix.mapPoints(&location2, 1); 887 matrix.mapPoints(&location2, 1);
879 // Use X scale and Y scale on Z and average the result 888 // Use X scale and Y scale on Z and average the result
880 SkPoint locationZ = SkPoint::Make(fLocation.fZ, fLocation.fZ); 889 SkPoint locationZ = SkPoint::Make(fLocation.fZ, fLocation.fZ);
881 matrix.mapVectors(&locationZ, 1); 890 matrix.mapVectors(&locationZ, 1);
882 SkPoint3 location = SkPoint3::Make(location2.fX, location2.fY, 891 SkPoint3 location = SkPoint3::Make(location2.fX, location2.fY,
883 SkScalarAve(locationZ.fX, locationZ.f Y)); 892 SkScalarAve(locationZ.fX, locationZ.f Y));
884 SkPoint target2 = SkPoint::Make(fTarget.fX, fTarget.fY); 893 SkPoint target2 = SkPoint::Make(fTarget.fX, fTarget.fY);
885 matrix.mapPoints(&target2, 1); 894 matrix.mapPoints(&target2, 1);
886 SkPoint targetZ = SkPoint::Make(fTarget.fZ, fTarget.fZ); 895 SkPoint targetZ = SkPoint::Make(fTarget.fZ, fTarget.fZ);
887 matrix.mapVectors(&targetZ, 1); 896 matrix.mapVectors(&targetZ, 1);
888 SkPoint3 target = SkPoint3::Make(target2.fX, target2.fY, 897 SkPoint3 target = SkPoint3::Make(target2.fX, target2.fY,
889 SkScalarAve(targetZ.fX, targetZ.fY)); 898 SkScalarAve(targetZ.fX, targetZ.fY));
890 SkPoint3 s = target - location; 899 SkPoint3 s = target - location;
891 s.normalize(); 900 fast_normalize(&s);
892 return new SkSpotLight(location, 901 return new SkSpotLight(location,
893 target, 902 target,
894 fSpecularExponent, 903 fSpecularExponent,
895 fCosOuterConeAngle, 904 fCosOuterConeAngle,
896 fCosInnerConeAngle, 905 fCosInnerConeAngle,
897 fConeScale, 906 fConeScale,
898 s, 907 s,
899 color()); 908 color());
900 } 909 }
901 910
902 SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const { 911 SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const {
903 SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x), 912 SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x),
904 fLocation.fY - SkIntToScalar(y), 913 fLocation.fY - SkIntToScalar(y),
905 fLocation.fZ - SkScalarMul(SkIntToSc alar(z), 914 fLocation.fZ - SkScalarMul(SkIntToSc alar(z),
906 surfaceSc ale)); 915 surfaceSc ale));
907 direction.normalize(); 916 fast_normalize(&direction);
908 return direction; 917 return direction;
909 }; 918 };
910 SkPoint3 lightColor(const SkPoint3& surfaceToLight) const { 919 SkPoint3 lightColor(const SkPoint3& surfaceToLight) const {
911 SkScalar cosAngle = -surfaceToLight.dot(fS); 920 SkScalar cosAngle = -surfaceToLight.dot(fS);
912 SkScalar scale = 0; 921 SkScalar scale = 0;
913 if (cosAngle >= fCosOuterConeAngle) { 922 if (cosAngle >= fCosOuterConeAngle) {
914 scale = SkScalarPow(cosAngle, fSpecularExponent); 923 scale = SkScalarPow(cosAngle, fSpecularExponent);
915 if (cosAngle < fCosInnerConeAngle) { 924 if (cosAngle < fCosInnerConeAngle) {
916 scale = SkScalarMul(scale, cosAngle - fCosOuterConeAngle); 925 scale = SkScalarMul(scale, cosAngle - fCosOuterConeAngle);
917 scale *= fConeScale; 926 scale *= fConeScale;
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 2024
2016 fsBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight); 2025 fsBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight);
2017 } 2026 }
2018 2027
2019 #endif 2028 #endif
2020 2029
2021 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter) 2030 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter)
2022 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter) 2031 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter)
2023 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter) 2032 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter)
2024 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 2033 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698