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

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: 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 inline void fast_normalize(SkPoint3* vector) {
reed1 2015/07/16 19:44:50 static inline ...
jvanverth1 2015/07/16 19:47:55 Done.
64 SkScalar magSq = vector->dot(*vector) + SK_ScalarNearlyZero;
reed1 2015/07/16 19:44:50 // add a tiny bit so we don't have to worry about
jvanverth1 2015/07/16 19:47:55 Done.
65 SkScalar scale = sk_float_rsqrt(magSq);
66 vector->fX *= scale;
67 vector->fY *= scale;
68 vector->fZ *= scale;
69 }
70
63 class DiffuseLightingType { 71 class DiffuseLightingType {
64 public: 72 public:
65 DiffuseLightingType(SkScalar kd) 73 DiffuseLightingType(SkScalar kd)
66 : fKD(kd) {} 74 : fKD(kd) {}
67 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, 75 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight,
68 const SkPoint3& lightColor) const { 76 const SkPoint3& lightColor) const {
69 SkScalar colorScale = SkScalarMul(fKD, normal.dot(surfaceTolight)); 77 SkScalar colorScale = SkScalarMul(fKD, normal.dot(surfaceTolight));
70 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); 78 colorScale = SkScalarClampMax(colorScale, SK_Scalar1);
71 SkPoint3 color = lightColor.makeScale(colorScale); 79 SkPoint3 color = lightColor.makeScale(colorScale);
72 return SkPackARGB32(255, 80 return SkPackARGB32(255,
(...skipping 10 matching lines...) Expand all
83 } 91 }
84 92
85 class SpecularLightingType { 93 class SpecularLightingType {
86 public: 94 public:
87 SpecularLightingType(SkScalar ks, SkScalar shininess) 95 SpecularLightingType(SkScalar ks, SkScalar shininess)
88 : fKS(ks), fShininess(shininess) {} 96 : fKS(ks), fShininess(shininess) {}
89 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, 97 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight,
90 const SkPoint3& lightColor) const { 98 const SkPoint3& lightColor) const {
91 SkPoint3 halfDir(surfaceTolight); 99 SkPoint3 halfDir(surfaceTolight);
92 halfDir.fZ += SK_Scalar1; // eye position is always (0, 0, 1) 100 halfDir.fZ += SK_Scalar1; // eye position is always (0, 0, 1)
93 halfDir.normalize(); 101 fast_normalize(&halfDir);
94 SkScalar colorScale = SkScalarMul(fKS, 102 SkScalar colorScale = SkScalarMul(fKS,
95 SkScalarPow(normal.dot(halfDir), fShininess)); 103 SkScalarPow(normal.dot(halfDir), fShininess));
96 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); 104 colorScale = SkScalarClampMax(colorScale, SK_Scalar1);
97 SkPoint3 color = lightColor.makeScale(colorScale); 105 SkPoint3 color = lightColor.makeScale(colorScale);
98 return SkPackARGB32(SkClampMax(SkScalarRoundToInt(max_component(color)), 255), 106 return SkPackARGB32(SkClampMax(SkScalarRoundToInt(max_component(color)), 255),
99 SkClampMax(SkScalarRoundToInt(color.fX), 255), 107 SkClampMax(SkScalarRoundToInt(color.fX), 255),
100 SkClampMax(SkScalarRoundToInt(color.fY), 255), 108 SkClampMax(SkScalarRoundToInt(color.fY), 255),
101 SkClampMax(SkScalarRoundToInt(color.fZ), 255)); 109 SkClampMax(SkScalarRoundToInt(color.fZ), 255));
102 } 110 }
103 private: 111 private:
104 SkScalar fKS; 112 SkScalar fKS;
105 SkScalar fShininess; 113 SkScalar fShininess;
106 }; 114 };
107 115
108 inline SkScalar sobel(int a, int b, int c, int d, int e, int f, SkScalar scale) { 116 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); 117 return SkScalarMul(SkIntToScalar(-a + b - 2 * c + 2 * d -e + f), scale);
110 } 118 }
111 119
112 inline SkPoint3 pointToNormal(SkScalar x, SkScalar y, SkScalar surfaceScale) { 120 inline SkPoint3 pointToNormal(SkScalar x, SkScalar y, SkScalar surfaceScale) {
113 SkPoint3 vector = SkPoint3::Make(SkScalarMul(-x, surfaceScale), 121 SkPoint3 vector = SkPoint3::Make(SkScalarMul(-x, surfaceScale),
114 SkScalarMul(-y, surfaceScale), 122 SkScalarMul(-y, surfaceScale),
115 SK_Scalar1); 123 SK_Scalar1);
116 vector.normalize(); 124 fast_normalize(&vector);
117 return vector; 125 return vector;
118 } 126 }
119 127
120 inline SkPoint3 topLeftNormal(int m[9], SkScalar surfaceScale) { 128 inline SkPoint3 topLeftNormal(int m[9], SkScalar surfaceScale) {
121 return pointToNormal(sobel(0, 0, m[4], m[5], m[7], m[8], gTwoThirds), 129 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), 130 sobel(0, 0, m[4], m[7], m[5], m[8], gTwoThirds),
123 surfaceScale); 131 surfaceScale);
124 } 132 }
125 133
126 inline SkPoint3 topNormal(int m[9], SkScalar surfaceScale) { 134 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 { 801 class SkPointLight : public SkLight {
794 public: 802 public:
795 SkPointLight(const SkPoint3& location, SkColor color) 803 SkPointLight(const SkPoint3& location, SkColor color)
796 : INHERITED(color), fLocation(location) {} 804 : INHERITED(color), fLocation(location) {}
797 805
798 SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const { 806 SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const {
799 SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x), 807 SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x),
800 fLocation.fY - SkIntToScalar(y), 808 fLocation.fY - SkIntToScalar(y),
801 fLocation.fZ - SkScalarMul(SkIntToSc alar(z), 809 fLocation.fZ - SkScalarMul(SkIntToSc alar(z),
802 surfaceSc ale)); 810 surfaceSc ale));
803 direction.normalize(); 811 fast_normalize(&direction);
804 return direction; 812 return direction;
805 }; 813 };
806 const SkPoint3& lightColor(const SkPoint3&) const { return this->color(); } 814 const SkPoint3& lightColor(const SkPoint3&) const { return this->color(); }
807 LightType type() const override { return kPoint_LightType; } 815 LightType type() const override { return kPoint_LightType; }
808 const SkPoint3& location() const { return fLocation; } 816 const SkPoint3& location() const { return fLocation; }
809 GrGLLight* createGLLight() const override { 817 GrGLLight* createGLLight() const override {
810 #if SK_SUPPORT_GPU 818 #if SK_SUPPORT_GPU
811 return SkNEW(GrGLPointLight); 819 return SkNEW(GrGLPointLight);
812 #else 820 #else
813 SkDEBUGFAIL("Should not call in GPU-less build"); 821 SkDEBUGFAIL("Should not call in GPU-less build");
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 const SkPoint3& target, 867 const SkPoint3& target,
860 SkScalar specularExponent, 868 SkScalar specularExponent,
861 SkScalar cutoffAngle, 869 SkScalar cutoffAngle,
862 SkColor color) 870 SkColor color)
863 : INHERITED(color), 871 : INHERITED(color),
864 fLocation(location), 872 fLocation(location),
865 fTarget(target), 873 fTarget(target),
866 fSpecularExponent(SkScalarPin(specularExponent, kSpecularExponentMin, kSp ecularExponentMax)) 874 fSpecularExponent(SkScalarPin(specularExponent, kSpecularExponentMin, kSp ecularExponentMax))
867 { 875 {
868 fS = target - location; 876 fS = target - location;
869 fS.normalize(); 877 fast_normalize(&fS);
870 fCosOuterConeAngle = SkScalarCos(SkDegreesToRadians(cutoffAngle)); 878 fCosOuterConeAngle = SkScalarCos(SkDegreesToRadians(cutoffAngle));
871 const SkScalar antiAliasThreshold = 0.016f; 879 const SkScalar antiAliasThreshold = 0.016f;
872 fCosInnerConeAngle = fCosOuterConeAngle + antiAliasThreshold; 880 fCosInnerConeAngle = fCosOuterConeAngle + antiAliasThreshold;
873 fConeScale = SkScalarInvert(antiAliasThreshold); 881 fConeScale = SkScalarInvert(antiAliasThreshold);
874 } 882 }
875 883
876 SkLight* transform(const SkMatrix& matrix) const override { 884 SkLight* transform(const SkMatrix& matrix) const override {
877 SkPoint location2 = SkPoint::Make(fLocation.fX, fLocation.fY); 885 SkPoint location2 = SkPoint::Make(fLocation.fX, fLocation.fY);
878 matrix.mapPoints(&location2, 1); 886 matrix.mapPoints(&location2, 1);
879 // Use X scale and Y scale on Z and average the result 887 // Use X scale and Y scale on Z and average the result
880 SkPoint locationZ = SkPoint::Make(fLocation.fZ, fLocation.fZ); 888 SkPoint locationZ = SkPoint::Make(fLocation.fZ, fLocation.fZ);
881 matrix.mapVectors(&locationZ, 1); 889 matrix.mapVectors(&locationZ, 1);
882 SkPoint3 location = SkPoint3::Make(location2.fX, location2.fY, 890 SkPoint3 location = SkPoint3::Make(location2.fX, location2.fY,
883 SkScalarAve(locationZ.fX, locationZ.f Y)); 891 SkScalarAve(locationZ.fX, locationZ.f Y));
884 SkPoint target2 = SkPoint::Make(fTarget.fX, fTarget.fY); 892 SkPoint target2 = SkPoint::Make(fTarget.fX, fTarget.fY);
885 matrix.mapPoints(&target2, 1); 893 matrix.mapPoints(&target2, 1);
886 SkPoint targetZ = SkPoint::Make(fTarget.fZ, fTarget.fZ); 894 SkPoint targetZ = SkPoint::Make(fTarget.fZ, fTarget.fZ);
887 matrix.mapVectors(&targetZ, 1); 895 matrix.mapVectors(&targetZ, 1);
888 SkPoint3 target = SkPoint3::Make(target2.fX, target2.fY, 896 SkPoint3 target = SkPoint3::Make(target2.fX, target2.fY,
889 SkScalarAve(targetZ.fX, targetZ.fY)); 897 SkScalarAve(targetZ.fX, targetZ.fY));
890 SkPoint3 s = target - location; 898 SkPoint3 s = target - location;
891 s.normalize(); 899 fast_normalize(&s);
892 return new SkSpotLight(location, 900 return new SkSpotLight(location,
893 target, 901 target,
894 fSpecularExponent, 902 fSpecularExponent,
895 fCosOuterConeAngle, 903 fCosOuterConeAngle,
896 fCosInnerConeAngle, 904 fCosInnerConeAngle,
897 fConeScale, 905 fConeScale,
898 s, 906 s,
899 color()); 907 color());
900 } 908 }
901 909
902 SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const { 910 SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const {
903 SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x), 911 SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x),
904 fLocation.fY - SkIntToScalar(y), 912 fLocation.fY - SkIntToScalar(y),
905 fLocation.fZ - SkScalarMul(SkIntToSc alar(z), 913 fLocation.fZ - SkScalarMul(SkIntToSc alar(z),
906 surfaceSc ale)); 914 surfaceSc ale));
907 direction.normalize(); 915 fast_normalize(&direction);
908 return direction; 916 return direction;
909 }; 917 };
910 SkPoint3 lightColor(const SkPoint3& surfaceToLight) const { 918 SkPoint3 lightColor(const SkPoint3& surfaceToLight) const {
911 SkScalar cosAngle = -surfaceToLight.dot(fS); 919 SkScalar cosAngle = -surfaceToLight.dot(fS);
912 SkScalar scale = 0; 920 SkScalar scale = 0;
913 if (cosAngle >= fCosOuterConeAngle) { 921 if (cosAngle >= fCosOuterConeAngle) {
914 scale = SkScalarPow(cosAngle, fSpecularExponent); 922 scale = SkScalarPow(cosAngle, fSpecularExponent);
915 if (cosAngle < fCosInnerConeAngle) { 923 if (cosAngle < fCosInnerConeAngle) {
916 scale = SkScalarMul(scale, cosAngle - fCosOuterConeAngle); 924 scale = SkScalarMul(scale, cosAngle - fCosOuterConeAngle);
917 scale *= fConeScale; 925 scale *= fConeScale;
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 2023
2016 fsBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight); 2024 fsBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight);
2017 } 2025 }
2018 2026
2019 #endif 2027 #endif
2020 2028
2021 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter) 2029 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter)
2022 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter) 2030 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter)
2023 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter) 2031 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter)
2024 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 2032 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