Particle cleanup: split SkParticleBinding out of SkParticleEffect
Also simplify type registration.
Change-Id: Ia47febb2ae2cd5821476c3dd33a688b688aa6d6d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/238359
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/modules/canvaskit/particles_bindings.cpp b/modules/canvaskit/particles_bindings.cpp
index 5003ef1..a0c4366 100644
--- a/modules/canvaskit/particles_bindings.cpp
+++ b/modules/canvaskit/particles_bindings.cpp
@@ -8,7 +8,6 @@
#include "include/core/SkCanvas.h"
#include "include/core/SkTypes.h"
#include "include/utils/SkRandom.h"
-#include "modules/particles/include/SkParticleDrawable.h"
#include "modules/particles/include/SkParticleEffect.h"
#include "modules/particles/include/SkParticleSerialization.h"
@@ -29,9 +28,7 @@
function("MakeParticles", optional_override([](std::string json)->sk_sp<SkParticleEffect> {
static bool didInit = false;
if (!didInit) {
- REGISTER_REFLECTED(SkReflected);
- SkParticleBinding::RegisterBindingTypes();
- SkParticleDrawable::RegisterDrawableTypes();
+ SkParticleEffect::RegisterParticleTypes();
didInit = true;
}
SkRandom r;
diff --git a/modules/particles/include/SkParticleBinding.h b/modules/particles/include/SkParticleBinding.h
new file mode 100644
index 0000000..f3d7b15
--- /dev/null
+++ b/modules/particles/include/SkParticleBinding.h
@@ -0,0 +1,75 @@
+/*
+* Copyright 2019 Google LLC
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef SkParticleBinding_DEFINED
+#define SkParticleBinding_DEFINED
+
+#include "include/core/SkString.h"
+#include "modules/particles/include/SkReflected.h"
+#include "src/sksl/SkSLExternalValue.h"
+
+#include <memory>
+
+struct SkCurve;
+struct SkColorCurve;
+class SkRandom;
+
+namespace SkSL {
+ class Compiler;
+}
+
+class SkParticleExternalValue : public SkSL::ExternalValue {
+public:
+ SkParticleExternalValue(const char* name, SkSL::Compiler& compiler, const SkSL::Type& type)
+ : SkSL::ExternalValue(name, type)
+ , fCompiler(compiler)
+ , fRandom(nullptr) {
+ }
+
+ void setRandom(SkRandom* random) { fRandom = random; }
+
+protected:
+ SkSL::Compiler& fCompiler;
+ SkRandom* fRandom;
+};
+
+class SkParticleBinding : public SkReflected {
+public:
+ SkParticleBinding(const char* name = "name") : fName(name) {}
+
+ REFLECTED_ABSTRACT(SkParticleBinding, SkReflected)
+
+ void visitFields(SkFieldVisitor* v) override;
+ virtual std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler&) = 0;
+
+ static void RegisterBindingTypes();
+
+ /*
+ * All SkParticleBinding objects expose a particular native object to an effect's SkSL code.
+ * In all cases, the 'name' is the symbol that will be used to access the object from the SkSL.
+ * Each binding is a callable object, so the SkSL name behaves like a function. The behavior of
+ * each kind of binding is described below.
+ */
+
+ // Binds an SkCurve to an effect's SkSL. The curve is a one-dimensional function, described
+ // in SkCurve.h. It is called in the SkSL as 'name(t)', and returns a single float value.
+ static sk_sp<SkParticleBinding> MakeCurve(const char* name, const SkCurve& curve);
+
+ // Binds an SkColorCurve to an effect's SkSL. The curve is a one-dimensional, function,
+ // described in SkCurve.h. It is called in the SkSL as 'name(t)', and returns a float4 value.
+ static sk_sp<SkParticleBinding> MakeColorCurve(const char* name, const SkColorCurve& curve);
+
+ // Binds an SkPath to an effect's SkSL. The path is specified using SVG syntax. It is called
+ // in the SkSL as 'name(t)'. 't' is a normalized distance along the path. This returns a float4
+ // value, containing the position in .xy, and the normal in .zw.
+ static sk_sp<SkParticleBinding> MakePathBinding(const char* name, const char* path);
+
+protected:
+ SkString fName;
+};
+
+#endif // SkParticleBinding_DEFINED
diff --git a/modules/particles/include/SkParticleEffect.h b/modules/particles/include/SkParticleEffect.h
index cf7066c..3d7454e 100644
--- a/modules/particles/include/SkParticleEffect.h
+++ b/modules/particles/include/SkParticleEffect.h
@@ -14,56 +14,19 @@
#include "include/private/SkTemplates.h"
#include "include/utils/SkRandom.h"
#include "modules/particles/include/SkParticleData.h"
-#include "modules/particles/include/SkReflected.h"
#include <memory>
class SkCanvas;
-struct SkCurve;
-struct SkColorCurve;
+class SkFieldVisitor;
+class SkParticleBinding;
class SkParticleDrawable;
class SkParticleExternalValue;
namespace SkSL {
struct ByteCode;
- class Compiler;
}
-class SkParticleBinding : public SkReflected {
-public:
- SkParticleBinding(const char* name = "name") : fName(name) {}
-
- REFLECTED_ABSTRACT(SkParticleBinding, SkReflected)
-
- void visitFields(SkFieldVisitor* v) override;
- virtual std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler&) = 0;
-
- static void RegisterBindingTypes();
-
- /*
- * All SkParticleBinding objects expose a particular native object to an effect's SkSL code.
- * In all cases, the 'name' is the symbol that will be used to access the object from the SkSL.
- * Each binding is a callable object, so the SkSL name behaves like a function. The behavior of
- * each kind of binding is described below.
- */
-
- // Binds an SkCurve to an effect's SkSL. The curve is a one-dimensional function, described
- // in SkCurve.h. It is called in the SkSL as 'name(t)', and returns a single float value.
- static sk_sp<SkParticleBinding> MakeCurve(const char* name, const SkCurve& curve);
-
- // Binds an SkColorCurve to an effect's SkSL. The curve is a one-dimensional, function,
- // described in SkCurve.h. It is called in the SkSL as 'name(t)', and returns a float4 value.
- static sk_sp<SkParticleBinding> MakeColorCurve(const char* name, const SkColorCurve& curve);
-
- // Binds an SkPath to an effect's SkSL. The path is specified using SVG syntax. It is called
- // in the SkSL as 'name(t)'. 't' is a normalized distance along the path. This returns a float4
- // value, containing the position in .xy, and the normal in .zw.
- static sk_sp<SkParticleBinding> MakePathBinding(const char* name, const char* path);
-
-protected:
- SkString fName;
-};
-
class SkParticleEffectParams : public SkRefCnt {
public:
SkParticleEffectParams();
@@ -137,6 +100,8 @@
bool isAlive() const { return fSpawnTime >= 0; }
int getCount() const { return fCount; }
+ static void RegisterParticleTypes();
+
private:
void setCapacity(int capacity);
diff --git a/modules/particles/particles.gni b/modules/particles/particles.gni
index 0a7ca8c..49a313a 100644
--- a/modules/particles/particles.gni
+++ b/modules/particles/particles.gni
@@ -8,6 +8,7 @@
skia_particle_sources = [
"$_src/SkCurve.cpp",
+ "$_src/SkParticleBinding.cpp",
"$_src/SkParticleDrawable.cpp",
"$_src/SkParticleEffect.cpp",
"$_src/SkReflected.cpp",
diff --git a/modules/particles/src/SkParticleBinding.cpp b/modules/particles/src/SkParticleBinding.cpp
new file mode 100644
index 0000000..8bf8757
--- /dev/null
+++ b/modules/particles/src/SkParticleBinding.cpp
@@ -0,0 +1,268 @@
+/*
+* Copyright 2019 Google LLC
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "modules/particles/include/SkParticleBinding.h"
+
+#include "include/core/SkContourMeasure.h"
+#include "include/core/SkPath.h"
+#include "include/utils/SkParsePath.h"
+#include "include/utils/SkRandom.h"
+#include "include/utils/SkTextUtils.h"
+#include "modules/particles/include/SkCurve.h"
+#include "modules/particles/include/SkReflected.h"
+#include "src/sksl/SkSLCompiler.h"
+
+void SkParticleBinding::visitFields(SkFieldVisitor* v) {
+ v->visit("Name", fName);
+}
+
+// Exposes an SkCurve as an external, callable value. c(x) returns a float.
+class SkCurveExternalValue : public SkParticleExternalValue {
+public:
+ SkCurveExternalValue(const char* name, SkSL::Compiler& compiler, const SkCurve& curve)
+ : SkParticleExternalValue(name, compiler, *compiler.context().fFloat_Type)
+ , fCurve(curve) { }
+
+ bool canCall() const override { return true; }
+ int callParameterCount() const override { return 1; }
+ void getCallParameterTypes(const SkSL::Type** outTypes) const override {
+ outTypes[0] = fCompiler.context().fFloat_Type.get();
+ }
+
+ void call(int index, float* arguments, float* outReturn) override {
+ *outReturn = fCurve.eval(*arguments, fRandom[index]);
+ }
+
+private:
+ SkCurve fCurve;
+};
+
+class SkCurveBinding : public SkParticleBinding {
+public:
+ SkCurveBinding(const char* name = "", const SkCurve& curve = 0.0f)
+ : SkParticleBinding(name)
+ , fCurve(curve) {}
+
+ REFLECTED(SkCurveBinding, SkParticleBinding)
+
+ void visitFields(SkFieldVisitor* v) override {
+ SkParticleBinding::visitFields(v);
+ v->visit("Curve", fCurve);
+ }
+
+ std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler& compiler) override {
+ return std::unique_ptr<SkParticleExternalValue>(
+ new SkCurveExternalValue(fName.c_str(), compiler, fCurve));
+ }
+
+private:
+ SkCurve fCurve;
+};
+
+// Exposes an SkColorCurve as an external, callable value. c(x) returns a float4.
+class SkColorCurveExternalValue : public SkParticleExternalValue {
+public:
+ SkColorCurveExternalValue(const char* name, SkSL::Compiler& compiler, const SkColorCurve& curve)
+ : SkParticleExternalValue(name, compiler, *compiler.context().fFloat4_Type)
+ , fCurve(curve) {
+ }
+
+ bool canCall() const override { return true; }
+ int callParameterCount() const override { return 1; }
+ void getCallParameterTypes(const SkSL::Type** outTypes) const override {
+ outTypes[0] = fCompiler.context().fFloat_Type.get();
+ }
+
+ void call(int index, float* arguments, float* outReturn) override {
+ SkColor4f color = fCurve.eval(*arguments, fRandom[index]);
+ memcpy(outReturn, color.vec(), 4 * sizeof(float));
+ }
+
+private:
+ SkColorCurve fCurve;
+};
+
+class SkColorCurveBinding : public SkParticleBinding {
+public:
+ SkColorCurveBinding(const char* name = "",
+ const SkColorCurve& curve = SkColor4f{ 1.0f, 1.0f, 1.0f, 1.0f })
+ : SkParticleBinding(name)
+ , fCurve(curve) {
+ }
+
+ REFLECTED(SkColorCurveBinding, SkParticleBinding)
+
+ void visitFields(SkFieldVisitor* v) override {
+ SkParticleBinding::visitFields(v);
+ v->visit("Curve", fCurve);
+ }
+
+ std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler& compiler) override {
+ return std::unique_ptr<SkParticleExternalValue>(
+ new SkColorCurveExternalValue(fName.c_str(), compiler, fCurve));
+ }
+
+private:
+ SkColorCurve fCurve;
+};
+
+struct SkPathContours {
+ SkScalar fTotalLength;
+ SkTArray<sk_sp<SkContourMeasure>> fContours;
+
+ void rebuild(const SkPath& path) {
+ fTotalLength = 0;
+ fContours.reset();
+
+ SkContourMeasureIter iter(path, false);
+ while (auto contour = iter.next()) {
+ fContours.push_back(contour);
+ fTotalLength += contour->length();
+ }
+ }
+};
+
+// Exposes an SkPath as an external, callable value. p(x) returns a float4 { pos.xy, normal.xy }
+class SkPathExternalValue : public SkParticleExternalValue {
+public:
+ SkPathExternalValue(const char* name, SkSL::Compiler& compiler, const SkPathContours* path)
+ : SkParticleExternalValue(name, compiler, *compiler.context().fFloat4_Type)
+ , fPath(path) { }
+
+ bool canCall() const override { return true; }
+ int callParameterCount() const override { return 1; }
+ void getCallParameterTypes(const SkSL::Type** outTypes) const override {
+ outTypes[0] = fCompiler.context().fFloat_Type.get();
+ }
+
+ void call(int index, float* arguments, float* outReturn) override {
+ SkScalar len = fPath->fTotalLength * arguments[0];
+ int idx = 0;
+ while (idx < fPath->fContours.count() && len > fPath->fContours[idx]->length()) {
+ len -= fPath->fContours[idx++]->length();
+ }
+ SkVector localXAxis;
+ if (!fPath->fContours[idx]->getPosTan(len, (SkPoint*)outReturn, &localXAxis)) {
+ outReturn[0] = outReturn[1] = 0.0f;
+ localXAxis = { 1, 0 };
+ }
+ outReturn[2] = localXAxis.fY;
+ outReturn[3] = -localXAxis.fX;
+ }
+
+private:
+ const SkPathContours* fPath;
+};
+
+class SkPathBinding : public SkParticleBinding {
+public:
+ SkPathBinding(const char* name = "", const char* path = "")
+ : SkParticleBinding(name)
+ , fPath(path) {
+ this->rebuild();
+ }
+
+ REFLECTED(SkPathBinding, SkParticleBinding)
+
+ void visitFields(SkFieldVisitor* v) override {
+ SkString oldPath = fPath;
+
+ SkParticleBinding::visitFields(v);
+ v->visit("Path", fPath);
+
+ if (fPath != oldPath) {
+ this->rebuild();
+ }
+ }
+
+ std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler& compiler) override {
+ return std::unique_ptr<SkParticleExternalValue>(
+ new SkPathExternalValue(fName.c_str(), compiler, &fContours));
+ }
+
+private:
+ SkString fPath;
+
+ void rebuild() {
+ SkPath path;
+ if (SkParsePath::FromSVGString(fPath.c_str(), &path)) {
+ fContours.rebuild(path);
+ }
+ }
+
+ // Cached
+ SkPathContours fContours;
+};
+
+class SkTextBinding : public SkParticleBinding {
+public:
+ SkTextBinding(const char* name = "", const char* text = "", SkScalar fontSize = 96)
+ : SkParticleBinding(name)
+ , fText(text)
+ , fFontSize(fontSize) {
+ this->rebuild();
+ }
+
+ REFLECTED(SkTextBinding, SkParticleBinding)
+
+ void visitFields(SkFieldVisitor* v) override {
+ SkString oldText = fText;
+ SkScalar oldSize = fFontSize;
+
+ SkParticleBinding::visitFields(v);
+ v->visit("Text", fText);
+ v->visit("FontSize", fFontSize);
+
+ if (fText != oldText || fFontSize != oldSize) {
+ this->rebuild();
+ }
+ }
+
+ std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler& compiler) override {
+ return std::unique_ptr<SkParticleExternalValue>(
+ new SkPathExternalValue(fName.c_str(), compiler, &fContours));
+ }
+
+private:
+ SkString fText;
+ SkScalar fFontSize;
+
+ void rebuild() {
+ if (fText.isEmpty()) {
+ return;
+ }
+
+ SkFont font(nullptr, fFontSize);
+ SkPath path;
+ SkTextUtils::GetPath(fText.c_str(), fText.size(), SkTextEncoding::kUTF8, 0, 0, font, &path);
+ fContours.rebuild(path);
+ }
+
+ // Cached
+ SkPathContours fContours;
+};
+
+sk_sp<SkParticleBinding> SkParticleBinding::MakeCurve(const char* name, const SkCurve& curve) {
+ return sk_sp<SkParticleBinding>(new SkCurveBinding(name, curve));
+}
+
+sk_sp<SkParticleBinding> SkParticleBinding::MakeColorCurve(const char* name,
+ const SkColorCurve& curve) {
+ return sk_sp<SkParticleBinding>(new SkColorCurveBinding(name, curve));
+}
+
+sk_sp<SkParticleBinding> SkParticleBinding::MakePathBinding(const char* name, const char* path) {
+ return sk_sp<SkParticleBinding>(new SkPathBinding(name, path));
+}
+
+void SkParticleBinding::RegisterBindingTypes() {
+ REGISTER_REFLECTED(SkParticleBinding);
+ REGISTER_REFLECTED(SkCurveBinding);
+ REGISTER_REFLECTED(SkColorCurveBinding);
+ REGISTER_REFLECTED(SkPathBinding);
+ REGISTER_REFLECTED(SkTextBinding);
+}
diff --git a/modules/particles/src/SkParticleEffect.cpp b/modules/particles/src/SkParticleEffect.cpp
index 917a745..b166395 100644
--- a/modules/particles/src/SkParticleEffect.cpp
+++ b/modules/particles/src/SkParticleEffect.cpp
@@ -7,305 +7,25 @@
#include "modules/particles/include/SkParticleEffect.h"
-#include "include/core/SkCanvas.h"
-#include "include/core/SkContourMeasure.h"
#include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
-#include "include/core/SkRSXform.h"
-#include "include/private/SkColorData.h"
-#include "include/utils/SkParsePath.h"
-#include "include/utils/SkTextUtils.h"
#include "modules/particles/include/SkCurve.h"
+#include "modules/particles/include/SkParticleBinding.h"
#include "modules/particles/include/SkParticleDrawable.h"
#include "modules/particles/include/SkReflected.h"
#include "src/core/SkMakeUnique.h"
#include "src/sksl/SkSLByteCode.h"
#include "src/sksl/SkSLCompiler.h"
-#include "src/sksl/SkSLExternalValue.h"
-
-void SkParticleBinding::visitFields(SkFieldVisitor* v) {
- v->visit("Name", fName);
-}
-
-class SkParticleExternalValue : public SkSL::ExternalValue {
-public:
- SkParticleExternalValue(const char* name, SkSL::Compiler& compiler, const SkSL::Type& type)
- : INHERITED(name, type)
- , fCompiler(compiler)
- , fRandom(nullptr) {
- }
-
- void setRandom(SkRandom* random) { fRandom = random; }
-
-protected:
- SkSL::Compiler& fCompiler;
- SkRandom* fRandom;
- typedef SkSL::ExternalValue INHERITED;
-};
-
-// Exposes an SkCurve as an external, callable value. c(x) returns a float.
-class SkCurveExternalValue : public SkParticleExternalValue {
-public:
- SkCurveExternalValue(const char* name, SkSL::Compiler& compiler, const SkCurve& curve)
- : INHERITED(name, compiler, *compiler.context().fFloat_Type)
- , fCurve(curve) { }
-
- bool canCall() const override { return true; }
- int callParameterCount() const override { return 1; }
- void getCallParameterTypes(const SkSL::Type** outTypes) const override {
- outTypes[0] = fCompiler.context().fFloat_Type.get();
- }
-
- void call(int index, float* arguments, float* outReturn) override {
- *outReturn = fCurve.eval(*arguments, fRandom[index]);
- }
-
-private:
- SkCurve fCurve;
- typedef SkParticleExternalValue INHERITED;
-};
-
-class SkCurveBinding : public SkParticleBinding {
-public:
- SkCurveBinding(const char* name = "", const SkCurve& curve = 0.0f)
- : SkParticleBinding(name)
- , fCurve(curve) {}
-
- REFLECTED(SkCurveBinding, SkParticleBinding)
-
- void visitFields(SkFieldVisitor* v) override {
- SkParticleBinding::visitFields(v);
- v->visit("Curve", fCurve);
- }
-
- std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler& compiler) override {
- return std::unique_ptr<SkParticleExternalValue>(
- new SkCurveExternalValue(fName.c_str(), compiler, fCurve));
- }
-
-private:
- SkCurve fCurve;
-};
-
-// Exposes an SkColorCurve as an external, callable value. c(x) returns a float4.
-class SkColorCurveExternalValue : public SkParticleExternalValue {
-public:
- SkColorCurveExternalValue(const char* name, SkSL::Compiler& compiler, const SkColorCurve& curve)
- : INHERITED(name, compiler, *compiler.context().fFloat4_Type)
- , fCurve(curve) {
- }
-
- bool canCall() const override { return true; }
- int callParameterCount() const override { return 1; }
- void getCallParameterTypes(const SkSL::Type** outTypes) const override {
- outTypes[0] = fCompiler.context().fFloat_Type.get();
- }
-
- void call(int index, float* arguments, float* outReturn) override {
- SkColor4f color = fCurve.eval(*arguments, fRandom[index]);
- memcpy(outReturn, color.vec(), 4 * sizeof(float));
- }
-
-private:
- SkColorCurve fCurve;
- typedef SkParticleExternalValue INHERITED;
-};
-
-class SkColorCurveBinding : public SkParticleBinding {
-public:
- SkColorCurveBinding(const char* name = "",
- const SkColorCurve& curve = SkColor4f{ 1.0f, 1.0f, 1.0f, 1.0f })
- : SkParticleBinding(name)
- , fCurve(curve) {
- }
-
- REFLECTED(SkColorCurveBinding, SkParticleBinding)
-
- void visitFields(SkFieldVisitor* v) override {
- SkParticleBinding::visitFields(v);
- v->visit("Curve", fCurve);
- }
-
- std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler& compiler) override {
- return std::unique_ptr<SkParticleExternalValue>(
- new SkColorCurveExternalValue(fName.c_str(), compiler, fCurve));
- }
-
-private:
- SkColorCurve fCurve;
-};
-
-struct SkPathContours {
- SkScalar fTotalLength;
- SkTArray<sk_sp<SkContourMeasure>> fContours;
-
- void rebuild(const SkPath& path) {
- fTotalLength = 0;
- fContours.reset();
-
- SkContourMeasureIter iter(path, false);
- while (auto contour = iter.next()) {
- fContours.push_back(contour);
- fTotalLength += contour->length();
- }
- }
-};
-
-// Exposes an SkPath as an external, callable value. p(x) returns a float4 { pos.xy, normal.xy }
-class SkPathExternalValue : public SkParticleExternalValue {
-public:
- SkPathExternalValue(const char* name, SkSL::Compiler& compiler, const SkPathContours* path)
- : INHERITED(name, compiler, *compiler.context().fFloat4_Type)
- , fPath(path) { }
-
- bool canCall() const override { return true; }
- int callParameterCount() const override { return 1; }
- void getCallParameterTypes(const SkSL::Type** outTypes) const override {
- outTypes[0] = fCompiler.context().fFloat_Type.get();
- }
-
- void call(int index, float* arguments, float* outReturn) override {
- SkScalar len = fPath->fTotalLength * arguments[0];
- int idx = 0;
- while (idx < fPath->fContours.count() && len > fPath->fContours[idx]->length()) {
- len -= fPath->fContours[idx++]->length();
- }
- SkVector localXAxis;
- if (!fPath->fContours[idx]->getPosTan(len, (SkPoint*)outReturn, &localXAxis)) {
- outReturn[0] = outReturn[1] = 0.0f;
- localXAxis = { 1, 0 };
- }
- outReturn[2] = localXAxis.fY;
- outReturn[3] = -localXAxis.fX;
- }
-
-private:
- const SkPathContours* fPath;
- typedef SkParticleExternalValue INHERITED;
-};
-
-class SkPathBinding : public SkParticleBinding {
-public:
- SkPathBinding(const char* name = "", const char* path = "")
- : SkParticleBinding(name)
- , fPath(path) {
- this->rebuild();
- }
-
- REFLECTED(SkPathBinding, SkParticleBinding)
-
- void visitFields(SkFieldVisitor* v) override {
- SkString oldPath = fPath;
-
- SkParticleBinding::visitFields(v);
- v->visit("Path", fPath);
-
- if (fPath != oldPath) {
- this->rebuild();
- }
- }
-
- std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler& compiler) override {
- return std::unique_ptr<SkParticleExternalValue>(
- new SkPathExternalValue(fName.c_str(), compiler, &fContours));
- }
-
-private:
- SkString fPath;
-
- void rebuild() {
- SkPath path;
- if (SkParsePath::FromSVGString(fPath.c_str(), &path)) {
- fContours.rebuild(path);
- }
- }
-
- // Cached
- SkPathContours fContours;
-};
-
-class SkTextBinding : public SkParticleBinding {
-public:
- SkTextBinding(const char* name = "", const char* text = "", SkScalar fontSize = 96)
- : SkParticleBinding(name)
- , fText(text)
- , fFontSize(fontSize) {
- this->rebuild();
- }
-
- REFLECTED(SkTextBinding, SkParticleBinding)
-
- void visitFields(SkFieldVisitor* v) override {
- SkString oldText = fText;
- SkScalar oldSize = fFontSize;
-
- SkParticleBinding::visitFields(v);
- v->visit("Text", fText);
- v->visit("FontSize", fFontSize);
-
- if (fText != oldText || fFontSize != oldSize) {
- this->rebuild();
- }
- }
-
- std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler& compiler) override {
- return std::unique_ptr<SkParticleExternalValue>(
- new SkPathExternalValue(fName.c_str(), compiler, &fContours));
- }
-
-private:
- SkString fText;
- SkScalar fFontSize;
-
- void rebuild() {
- if (fText.isEmpty()) {
- return;
- }
-
- SkFont font(nullptr, fFontSize);
- SkPath path;
- SkTextUtils::GetPath(fText.c_str(), fText.size(), SkTextEncoding::kUTF8, 0, 0, font, &path);
- fContours.rebuild(path);
- }
-
- // Cached
- SkPathContours fContours;
-};
-
-sk_sp<SkParticleBinding> SkParticleBinding::MakeCurve(const char* name, const SkCurve& curve) {
- return sk_sp<SkParticleBinding>(new SkCurveBinding(name, curve));
-}
-
-sk_sp<SkParticleBinding> SkParticleBinding::MakeColorCurve(const char* name,
- const SkColorCurve& curve) {
- return sk_sp<SkParticleBinding>(new SkColorCurveBinding(name, curve));
-}
-
-sk_sp<SkParticleBinding> SkParticleBinding::MakePathBinding(const char* name, const char* path) {
- return sk_sp<SkParticleBinding>(new SkPathBinding(name, path));
-}
-
-void SkParticleBinding::RegisterBindingTypes() {
- REGISTER_REFLECTED(SkParticleBinding);
- REGISTER_REFLECTED(SkCurveBinding);
- REGISTER_REFLECTED(SkColorCurveBinding);
- REGISTER_REFLECTED(SkPathBinding);
- REGISTER_REFLECTED(SkTextBinding);
-}
// Exposes a particle's random generator as an external, readable value. read returns a float [0, 1)
class SkRandomExternalValue : public SkParticleExternalValue {
public:
SkRandomExternalValue(const char* name, SkSL::Compiler& compiler)
- : INHERITED(name, compiler, *compiler.context().fFloat_Type) {}
+ : SkParticleExternalValue(name, compiler, *compiler.context().fFloat_Type) {}
bool canRead() const override { return true; }
void read(int index, float* target) override {
*target = fRandom[index].nextF();
}
-
-private:
- typedef SkParticleExternalValue INHERITED;
};
static const char* kCodeHeader =
@@ -561,3 +281,9 @@
fCapacity = capacity;
fCount = SkTMin(fCount, fCapacity);
}
+
+void SkParticleEffect::RegisterParticleTypes() {
+ REGISTER_REFLECTED(SkReflected);
+ SkParticleBinding::RegisterBindingTypes();
+ SkParticleDrawable::RegisterDrawableTypes();
+}
diff --git a/tools/cpu_modules.cpp b/tools/cpu_modules.cpp
index 4354a73..a749ebf 100644
--- a/tools/cpu_modules.cpp
+++ b/tools/cpu_modules.cpp
@@ -5,17 +5,12 @@
* found in the LICENSE file.
*/
-#include "modules/particles/include/SkParticleDrawable.h"
#include "modules/particles/include/SkParticleEffect.h"
-#include "modules/particles/include/SkParticleSerialization.h"
-#include "modules/particles/include/SkReflected.h"
// Doesn't do anything important; just exists to show we can use modules/particles without the GPU
// backend being available.
int main(int argc, char** argv) {
// Register types for serialization
- REGISTER_REFLECTED(SkReflected);
- SkParticleBinding::RegisterBindingTypes();
- SkParticleDrawable::RegisterDrawableTypes();
+ SkParticleEffect::RegisterParticleTypes();
return 0;
}
diff --git a/tools/viewer/ParticlesSlide.cpp b/tools/viewer/ParticlesSlide.cpp
index f243327..b8ddf78 100644
--- a/tools/viewer/ParticlesSlide.cpp
+++ b/tools/viewer/ParticlesSlide.cpp
@@ -7,7 +7,6 @@
#include "tools/viewer/ParticlesSlide.h"
-#include "modules/particles/include/SkParticleDrawable.h"
#include "modules/particles/include/SkParticleEffect.h"
#include "modules/particles/include/SkParticleSerialization.h"
#include "modules/particles/include/SkReflected.h"
@@ -203,9 +202,7 @@
ParticlesSlide::ParticlesSlide() {
// Register types for serialization
- REGISTER_REFLECTED(SkReflected);
- SkParticleBinding::RegisterBindingTypes();
- SkParticleDrawable::RegisterDrawableTypes();
+ SkParticleEffect::RegisterParticleTypes();
fName = "Particles";
fPlayPosition.set(200.0f, 200.0f);
}