aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2017-06-16 16:55:15 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-16 23:38:29 +0000
commit0c182fc77e044edddb6606b7cf51b9a5b6c2eb54 (patch)
tree002ef1b360cc32846f49028f1c84236027cecbf8
parent5f970fe6bed7a40ba95365bfe3220f18699a9176 (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.cpp207
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);
}