1/*
2* Copyright 2019 Google LLC
3*
4* Use of this source code is governed by a BSD-style license that can be
5* found in the LICENSE file.
6*/
7
8#ifndef SkParticleBinding_DEFINED
9#define SkParticleBinding_DEFINED
10
11#include "include/core/SkString.h"
12#include "modules/particles/include/SkReflected.h"
13#include "src/sksl/ir/SkSLExternalFunction.h"
14
15#include <memory>
16
17class SkArenaAlloc;
18class SkParticleEffect;
19class SkParticleEffectParams;
20
21namespace skresources {
22    class ResourceProvider;
23}  // namespace skresources
24
25namespace SkSL {
26    class Compiler;
27}  // namespace SkSL
28
29namespace skvm {
30    struct Uniforms;
31}  // namespace skvm
32
33class SkParticleExternalFunction : public SkSL::ExternalFunction {
34public:
35    SkParticleExternalFunction(const char* name,
36                               SkSL::Compiler& compiler,
37                               const SkSL::Type& type,
38                               skvm::Uniforms* uniforms,
39                               SkArenaAlloc* alloc)
40            : SkSL::ExternalFunction(name, type)
41            , fCompiler(compiler)
42            , fUniforms(uniforms)
43            , fAlloc(alloc) {}
44
45protected:
46    SkSL::Compiler& fCompiler;
47    skvm::Uniforms* fUniforms;
48    SkArenaAlloc*   fAlloc;
49};
50
51class SkParticleBinding : public SkReflected {
52public:
53    SkParticleBinding(const char* name = "name") : fName(name) {}
54
55    REFLECTED_ABSTRACT(SkParticleBinding, SkReflected)
56
57    void visitFields(SkFieldVisitor* v) override;
58
59    virtual std::unique_ptr<SkParticleExternalFunction> toFunction(SkSL::Compiler&,
60                                                                   skvm::Uniforms*,
61                                                                   SkArenaAlloc*) = 0;
62    virtual void prepare(const skresources::ResourceProvider*) = 0;
63
64    static void RegisterBindingTypes();
65
66    /*
67     * All SkParticleBinding objects expose a particular native object to an effect's SkSL code.
68     * In all cases, the 'name' is the symbol that will be used to access the object from the SkSL.
69     * Each binding is a callable object, so the SkSL name behaves like a function. The behavior of
70     * each kind of binding is described below.
71     */
72
73    // float4 name(xy) -- Fetches RGBA data from an image. 'xy' are normalized image coordinates.
74    static sk_sp<SkParticleBinding> MakeImage(const char* name,
75                                              const char* imagePath, const char* imageName);
76
77    // float4 name(t) -- Fetches position and normal from an SkPath. 't' is the normalized distance
78    // along the path. The return value contains position in .xy and normal in .zw.
79    static sk_sp<SkParticleBinding> MakePath(const char* name,
80                                             const char* pathPath, const char* pathName);
81
82protected:
83    SkString fName;
84};
85
86#endif // SkParticleBinding_DEFINED
87