diff options
author | 2017-06-16 16:55:15 -0400 | |
---|---|---|
committer | 2017-06-16 23:38:29 +0000 | |
commit | 0c182fc77e044edddb6606b7cf51b9a5b6c2eb54 (patch) | |
tree | 002ef1b360cc32846f49028f1c84236027cecbf8 | |
parent | 5f970fe6bed7a40ba95365bfe3220f18699a9176 (diff) |
refactor lighting imagefilter to save codesize
Goal was to just remove template args and add virtuals where needed.
Ended up having to also move a couple of classes/helpers earlier in the file, but nothing beyond that.
Size savings (on Mac laptop) : 67896
Before:
8/8 MB 1 30.6ms 30.7ms 30.7ms 30.9ms 0% █▁▅▁▄▃▄▁▃▃ 8888 lightingspotlitspecular_large
8/8 MB 1 34.2ms 37.6ms 38.5ms 45.9ms 9% ▂▂▃▅▁▅█▂▅▂ 8888 lightingspotlitspecular_small
8/8 MB 1 31.3ms 35ms 34.6ms 38.4ms 7% ▁▄▅▆▆▁▇▃▂█ 8888 lightingdistantlitspecular_large
8/8 MB 1 29.9ms 33.5ms 34.3ms 39.2ms 8% ▁▅█▃▄▇▄▂▄▆ 8888 lightingdistantlitspecular_small
8/8 MB 1 30.4ms 34.1ms 34.5ms 40.7ms 11% ▂▄█▃▁▅▂▅▁▇ 8888 lightingpointlitspecular_large
8/8 MB 1 29.8ms 36.2ms 34.8ms 41.4ms 12% ▂▃▅▁▅▇▂▁▆█ 8888 lightingpointlitspecular_small
8/8 MB 1 16.3ms 19.5ms 20.5ms 26.6ms 17% ▁▆▃▃█▃▂▅▁▆ 8888 lightingspotlitdiffuse_large
8/8 MB 1 17.3ms 19.3ms 19.4ms 23.3ms 10% ▄▁▂▁▆▅▁▃▂█ 8888 lightingspotlitdiffuse_small
8/8 MB 1 12.7ms 14.9ms 17ms 27.9ms 30% ▂▁█▁▂▄▂▂▂▆ 8888 lightingdistantlitdiffuse_large
8/8 MB 1 12.4ms 14.5ms 15.8ms 24.7ms 23% ▁▂▅▂▁▃█▂▃▂ 8888 lightingdistantlitdiffuse_small
8/8 MB 1 13.6ms 14.9ms 16.6ms 22.5ms 22% ▁█▅▁▆▂▁▂▁█ 8888 lightingpointlitdiffuse_large
8/8 MB 1 13.8ms 17ms 16.5ms 19.2ms 11% ▆▆▁▁▆▅▅█▃▂ 8888 lightingpointlitdiffuse_small
After:
8/8 MB 1 23.5ms 23.6ms 23.8ms 25.1ms 2% ▃▁█▁▁▂▁▂▁▁ 8888 lightingspotlitspecular_large
8/8 MB 1 23.5ms 23.6ms 23.9ms 24.9ms 2% █▅▂▁▁▁▁▁▆▃ 8888 lightingspotlitspecular_small
8/8 MB 1 21.6ms 21.8ms 21.9ms 22.3ms 1% █▆▃▁▄▄▃▂▄▂ 8888 lightingdistantlitspecular_large
8/8 MB 1 21.6ms 21.7ms 21.9ms 22.7ms 2% █▅▂▂▂▁▂▂▂▃ 8888 lightingdistantlitspecular_small
8/8 MB 1 22.3ms 22.9ms 22.8ms 23.2ms 1% ▇▆▁▄▆▄▃█▄▆ 8888 lightingpointlitspecular_large
8/8 MB 1 22.1ms 22.2ms 22.5ms 23.6ms 3% ██▁▁▂▂▁▁▂▂ 8888 lightingpointlitspecular_small
8/8 MB 1 12.8ms 13ms 13ms 13.3ms 2% ▃▇█▇▁▅▄▃▂▄ 8888 lightingspotlitdiffuse_large
8/8 MB 1 12.8ms 13ms 13ms 13.2ms 1% ▄▃██▄▁▃▅▂▇ 8888 lightingspotlitdiffuse_small
8/8 MB 1 10.6ms 10.7ms 10.8ms 11.1ms 2% ▂▄██▂▁▃▃▂▂ 8888 lightingdistantlitdiffuse_large
8/8 MB 1 10.6ms 10.7ms 10.8ms 11.3ms 2% ▂▂▇█▃▁▂▅▁▂ 8888 lightingdistantlitdiffuse_small
8/8 MB 1 10.9ms 11.1ms 11.2ms 11.6ms 2% ▁▂▇▁█▃▂▂▇▁ 8888 lightingpointlitdiffuse_large
8/8 MB 1 10.9ms 11.1ms 11.1ms 11.5ms 2% ▄▃█▅▃▃▁▃▂▁ 8888 lightingpointlitdiffuse_small
Bug: skia:
Change-Id: I7542a5ca1f209a732630f646b4ceb4fb08150ce4
Reviewed-on: https://skia-review.googlesource.com/20155
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
-rw-r--r-- | src/effects/SkLightingImageFilter.cpp | 207 |
1 files changed, 89 insertions, 118 deletions
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index fe6a39a2c4..78f58993e0 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -77,12 +77,83 @@ static inline void fast_normalize(SkPoint3* vector) { vector->fZ *= scale; } -class DiffuseLightingType { +static SkPoint3 readPoint3(SkReadBuffer& buffer) { + SkPoint3 point; + point.fX = buffer.readScalar(); + point.fY = buffer.readScalar(); + point.fZ = buffer.readScalar(); + buffer.validate(SkScalarIsFinite(point.fX) && + SkScalarIsFinite(point.fY) && + SkScalarIsFinite(point.fZ)); + return point; +}; + +static void writePoint3(const SkPoint3& point, SkWriteBuffer& buffer) { + buffer.writeScalar(point.fX); + buffer.writeScalar(point.fY); + buffer.writeScalar(point.fZ); +}; + +class GrGLLight; +class SkImageFilterLight : public SkRefCnt { +public: + enum LightType { + kDistant_LightType, + kPoint_LightType, + kSpot_LightType, + }; + virtual LightType type() const = 0; + const SkPoint3& color() const { return fColor; } + virtual GrGLLight* createGLLight() const = 0; + virtual bool isEqual(const SkImageFilterLight& other) const { + return fColor == other.fColor; + } + virtual SkImageFilterLight* transform(const SkMatrix& matrix) const = 0; + + virtual sk_sp<SkImageFilterLight> makeColorSpace(SkColorSpaceXformer*) const = 0; + + // Defined below SkLight's subclasses. + void flattenLight(SkWriteBuffer& buffer) const; + static SkImageFilterLight* UnflattenLight(SkReadBuffer& buffer); + + virtual SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const = 0; + virtual SkPoint3 lightColor(const SkPoint3& surfaceToLight) const = 0; + +protected: + SkImageFilterLight(SkColor color) { + fColor = SkPoint3::Make(SkIntToScalar(SkColorGetR(color)), + SkIntToScalar(SkColorGetG(color)), + SkIntToScalar(SkColorGetB(color))); + } + SkImageFilterLight(const SkPoint3& color) + : fColor(color) {} + SkImageFilterLight(SkReadBuffer& buffer) { + fColor = readPoint3(buffer); + } + + virtual void onFlattenLight(SkWriteBuffer& buffer) const = 0; + + +private: + typedef SkRefCnt INHERITED; + SkPoint3 fColor; +}; + +class BaseLightingType { +public: + BaseLightingType() {} + virtual ~BaseLightingType() {} + + virtual SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, + const SkPoint3& lightColor) const= 0; +}; + +class DiffuseLightingType : public BaseLightingType { public: DiffuseLightingType(SkScalar kd) : fKD(kd) {} SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, - const SkPoint3& lightColor) const { + const SkPoint3& lightColor) const override { SkScalar colorScale = fKD * normal.dot(surfaceTolight); colorScale = SkScalarClampMax(colorScale, SK_Scalar1); SkPoint3 color = lightColor.makeScale(colorScale); @@ -99,12 +170,12 @@ static SkScalar max_component(const SkPoint3& p) { return p.x() > p.y() ? (p.x() > p.z() ? p.x() : p.z()) : (p.y() > p.z() ? p.y() : p.z()); } -class SpecularLightingType { +class SpecularLightingType : public BaseLightingType { public: SpecularLightingType(SkScalar ks, SkScalar shininess) : fKS(ks), fShininess(shininess) {} SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, - const SkPoint3& lightColor) const { + const SkPoint3& lightColor) const override { SkPoint3 halfDir(surfaceTolight); halfDir.fZ += SK_Scalar1; // eye position is always (0, 0, 1) fast_normalize(&halfDir); @@ -206,15 +277,14 @@ public: } }; -template <class LightingType, class LightType, class PixelFetcher> -static void lightBitmap(const LightingType& lightingType, - const SkImageFilterLight* light, +template <class PixelFetcher> +static void lightBitmap(const BaseLightingType& lightingType, + const SkImageFilterLight* l, const SkBitmap& src, SkBitmap* dst, SkScalar surfaceScale, const SkIRect& bounds) { SkASSERT(dst->width() == bounds.width() && dst->height() == bounds.height()); - const LightType* l = static_cast<const LightType*>(light); int left = bounds.left(), right = bounds.right(); int bottom = bounds.bottom(); int y = bounds.top(); @@ -298,39 +368,21 @@ static void lightBitmap(const LightingType& lightingType, } } -template <class LightingType, class LightType> -static void lightBitmap(const LightingType& lightingType, +static void lightBitmap(const BaseLightingType& lightingType, const SkImageFilterLight* light, const SkBitmap& src, SkBitmap* dst, SkScalar surfaceScale, const SkIRect& bounds) { if (src.bounds().contains(bounds)) { - lightBitmap<LightingType, LightType, UncheckedPixelFetcher>( + lightBitmap<UncheckedPixelFetcher>( lightingType, light, src, dst, surfaceScale, bounds); } else { - lightBitmap<LightingType, LightType, DecalPixelFetcher>( + lightBitmap<DecalPixelFetcher>( lightingType, light, src, dst, surfaceScale, bounds); } } -static SkPoint3 readPoint3(SkReadBuffer& buffer) { - SkPoint3 point; - point.fX = buffer.readScalar(); - point.fY = buffer.readScalar(); - point.fZ = buffer.readScalar(); - buffer.validate(SkScalarIsFinite(point.fX) && - SkScalarIsFinite(point.fY) && - SkScalarIsFinite(point.fZ)); - return point; -}; - -static void writePoint3(const SkPoint3& point, SkWriteBuffer& buffer) { - buffer.writeScalar(point.fX); - buffer.writeScalar(point.fY); - buffer.writeScalar(point.fZ); -}; - enum BoundaryMode { kTopLeft_BoundaryMode, kTop_BoundaryMode, @@ -751,47 +803,6 @@ class GrGLLight; /////////////////////////////////////////////////////////////////////////////// -class SkImageFilterLight : public SkRefCnt { -public: - enum LightType { - kDistant_LightType, - kPoint_LightType, - kSpot_LightType, - }; - virtual LightType type() const = 0; - const SkPoint3& color() const { return fColor; } - virtual GrGLLight* createGLLight() const = 0; - virtual bool isEqual(const SkImageFilterLight& other) const { - return fColor == other.fColor; - } - virtual SkImageFilterLight* transform(const SkMatrix& matrix) const = 0; - - virtual sk_sp<SkImageFilterLight> makeColorSpace(SkColorSpaceXformer*) const = 0; - - // Defined below SkLight's subclasses. - void flattenLight(SkWriteBuffer& buffer) const; - static SkImageFilterLight* UnflattenLight(SkReadBuffer& buffer); - -protected: - SkImageFilterLight(SkColor color) { - fColor = SkPoint3::Make(SkIntToScalar(SkColorGetR(color)), - SkIntToScalar(SkColorGetG(color)), - SkIntToScalar(SkColorGetB(color))); - } - SkImageFilterLight(const SkPoint3& color) - : fColor(color) {} - SkImageFilterLight(SkReadBuffer& buffer) { - fColor = readPoint3(buffer); - } - - virtual void onFlattenLight(SkWriteBuffer& buffer) const = 0; - - -private: - typedef SkRefCnt INHERITED; - SkPoint3 fColor; -}; - /////////////////////////////////////////////////////////////////////////////// static SkColor xform_color(const SkPoint3& color, SkColorSpaceXformer* xformer) { @@ -808,10 +819,10 @@ public: : INHERITED(color), fDirection(direction) { } - SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const { + SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const override { return fDirection; } - const SkPoint3& lightColor(const SkPoint3&) const { return this->color(); } + SkPoint3 lightColor(const SkPoint3&) const override { return this->color(); } LightType type() const override { return kDistant_LightType; } const SkPoint3& direction() const { return fDirection; } GrGLLight* createGLLight() const override { @@ -865,14 +876,14 @@ public: SkPointLight(const SkPoint3& location, SkColor color) : INHERITED(color), fLocation(location) {} - SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const { + SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const override { SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x), fLocation.fY - SkIntToScalar(y), fLocation.fZ - SkIntToScalar(z) * surfaceScale); fast_normalize(&direction); return direction; } - const SkPoint3& lightColor(const SkPoint3&) const { return this->color(); } + SkPoint3 lightColor(const SkPoint3&) const override { return this->color(); } LightType type() const override { return kPoint_LightType; } const SkPoint3& location() const { return fLocation; } GrGLLight* createGLLight() const override { @@ -979,14 +990,14 @@ public: color()); } - SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const { + SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const override { SkPoint3 direction = SkPoint3::Make(fLocation.fX - SkIntToScalar(x), fLocation.fY - SkIntToScalar(y), fLocation.fZ - SkIntToScalar(z) * surfaceScale); fast_normalize(&direction); return direction; } - SkPoint3 lightColor(const SkPoint3& surfaceToLight) const { + SkPoint3 lightColor(const SkPoint3& surfaceToLight) const override { SkScalar cosAngle = -surfaceToLight.dot(fS); SkScalar scale = 0; if (cosAngle >= fCosOuterConeAngle) { @@ -1316,32 +1327,12 @@ sk_sp<SkSpecialImage> SkDiffuseLightingImageFilter::onFilterImage(SkSpecialImage sk_sp<SkImageFilterLight> transformedLight(light()->transform(matrix)); DiffuseLightingType lightingType(fKD); - switch (transformedLight->type()) { - case SkImageFilterLight::kDistant_LightType: - lightBitmap<DiffuseLightingType, SkDistantLight>(lightingType, + lightBitmap(lightingType, transformedLight.get(), inputBM, &dst, surfaceScale(), bounds); - break; - case SkImageFilterLight::kPoint_LightType: - lightBitmap<DiffuseLightingType, SkPointLight>(lightingType, - transformedLight.get(), - inputBM, - &dst, - surfaceScale(), - bounds); - break; - case SkImageFilterLight::kSpot_LightType: - lightBitmap<DiffuseLightingType, SkSpotLight>(lightingType, - transformedLight.get(), - inputBM, - &dst, - surfaceScale(), - bounds); - break; - } return SkSpecialImage::MakeFromRaster(SkIRect::MakeWH(bounds.width(), bounds.height()), dst); @@ -1490,32 +1481,12 @@ sk_sp<SkSpecialImage> SkSpecularLightingImageFilter::onFilterImage(SkSpecialImag sk_sp<SkImageFilterLight> transformedLight(light()->transform(matrix)); - switch (transformedLight->type()) { - case SkImageFilterLight::kDistant_LightType: - lightBitmap<SpecularLightingType, SkDistantLight>(lightingType, + lightBitmap(lightingType, transformedLight.get(), inputBM, &dst, surfaceScale(), bounds); - break; - case SkImageFilterLight::kPoint_LightType: - lightBitmap<SpecularLightingType, SkPointLight>(lightingType, - transformedLight.get(), - inputBM, - &dst, - surfaceScale(), - bounds); - break; - case SkImageFilterLight::kSpot_LightType: - lightBitmap<SpecularLightingType, SkSpotLight>(lightingType, - transformedLight.get(), - inputBM, - &dst, - surfaceScale(), - bounds); - break; - } return SkSpecialImage::MakeFromRaster(SkIRect::MakeWH(bounds.width(), bounds.height()), dst); } |