blob: 8dc9e302fcb743495e3632bf964437436dd0b773 [file] [log] [blame]
Ethan Nicholas00543112018-07-31 09:44:36 -04001/*
2 * Copyright 2018 Google Inc.
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 GrSkSLFP_DEFINED
9#define GrSkSLFP_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkRefCnt.h"
Brian Osmanbd4f8722020-03-06 15:23:54 -050012#include "include/gpu/GrContextOptions.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/GrCaps.h"
14#include "src/gpu/GrCoordTransform.h"
15#include "src/gpu/GrFragmentProcessor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/sksl/SkSLCompiler.h"
17#include "src/sksl/SkSLPipelineStageCodeGenerator.h"
Mike Klein0ec1c572018-12-04 11:52:51 -050018#include <atomic>
Ethan Nicholas00543112018-07-31 09:44:36 -040019
Ethan Nicholas78aceb22018-08-31 16:13:58 -040020#if GR_TEST_UTILS
21#define GR_FP_SRC_STRING const char*
22#else
23#define GR_FP_SRC_STRING static const char*
24#endif
25
Robert Phillips1efecea2019-02-15 16:58:40 -050026class GrContext_Base;
Robert Phillips7f11fb52019-12-03 13:35:19 -050027class GrShaderCaps;
Brian Osman9bfd5952020-02-05 10:51:44 -050028class SkData;
Brian Osman7b1678a2019-12-16 09:17:25 -050029class SkRuntimeEffect;
Ethan Nicholas00543112018-07-31 09:44:36 -040030
31class GrSkSLFP : public GrFragmentProcessor {
32public:
33 /**
Brian Osman7b1678a2019-12-16 09:17:25 -050034 * Creates a new fragment processor from an SkRuntimeEffect and a struct of inputs to the
Ethan Nicholas31cff272019-09-26 13:04:48 -040035 * program. The input struct's type is derived from the 'in' and 'uniform' variables in the SkSL
36 * source, so e.g. the shader:
Ethan Nicholas00543112018-07-31 09:44:36 -040037 *
38 * in bool dither;
Ethan Nicholas31cff272019-09-26 13:04:48 -040039 * uniform float x;
40 * uniform float y;
Ethan Nicholas00543112018-07-31 09:44:36 -040041 * ....
42 *
43 * would expect a pointer to a struct set up like:
44 *
45 * struct {
46 * bool dither;
47 * float x;
48 * float y;
49 * };
50 *
Ethan Nicholas31cff272019-09-26 13:04:48 -040051 * While both 'in' and 'uniform' variables go into this struct, the difference between them is
52 * that 'in' variables are statically "baked in" to the generated code, becoming literals,
53 * whereas uniform variables may be changed from invocation to invocation without having to
54 * recompile the shader.
55 *
56 * As the decision of whether to create a new shader or just upload new uniforms all happens
57 * behind the scenes, the difference between the two from an end-user perspective is primarily
58 * in performance: on the one hand, changing the value of an 'in' variable is very expensive
59 * (requiring the compiler to regenerate the code, upload a new shader to the GPU, and so
60 * forth), but on the other hand the compiler can optimize around its value because it is known
61 * at compile time. 'in' variables are therefore suitable for things like flags, where there are
62 * only a few possible values and a known-in-advance value can cause entire chunks of code to
63 * become dead (think static @ifs), while 'uniform's are used for continuous values like colors
64 * and coordinates, where it would be silly to create a separate shader for each possible set of
65 * values. Other than the (significant) performance implications, the only difference between
66 * the two is that 'in' variables can be used in static @if / @switch tests. When in doubt, use
67 * 'uniform'.
Ethan Nicholas00543112018-07-31 09:44:36 -040068 */
Brian Osman7b1678a2019-12-16 09:17:25 -050069 static std::unique_ptr<GrSkSLFP> Make(GrContext_Base* context,
70 sk_sp<SkRuntimeEffect> effect,
71 const char* name,
Ethan Nicholasafe2c902020-04-28 13:55:02 -040072 sk_sp<SkData> inputs);
Ethan Nicholasa70693b2019-03-04 13:07:36 -050073
Ethan Nicholas00543112018-07-31 09:44:36 -040074 const char* name() const override;
75
Ethan Nicholasce008112018-08-30 09:19:50 -040076 void addChild(std::unique_ptr<GrFragmentProcessor> child);
77
Ethan Nicholas00543112018-07-31 09:44:36 -040078 std::unique_ptr<GrFragmentProcessor> clone() const override;
79
80private:
Brian Osmanbd4f8722020-03-06 15:23:54 -050081 using ShaderErrorHandler = GrContextOptions::ShaderErrorHandler;
82
83 GrSkSLFP(sk_sp<const GrShaderCaps> shaderCaps, ShaderErrorHandler* shaderErrorHandler,
Ethan Nicholasafe2c902020-04-28 13:55:02 -040084 sk_sp<SkRuntimeEffect> effect, const char* name, sk_sp<SkData> inputs);
Ethan Nicholas00543112018-07-31 09:44:36 -040085
86 GrSkSLFP(const GrSkSLFP& other);
87
88 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
89
90 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
91
92 bool onIsEqual(const GrFragmentProcessor&) const override;
93
Brian Osman7b1678a2019-12-16 09:17:25 -050094 sk_sp<const GrShaderCaps> fShaderCaps;
Brian Osmanbd4f8722020-03-06 15:23:54 -050095 ShaderErrorHandler* fShaderErrorHandler;
Ethan Nicholas00543112018-07-31 09:44:36 -040096
Brian Osman7b1678a2019-12-16 09:17:25 -050097 sk_sp<SkRuntimeEffect> fEffect;
98 const char* fName;
Brian Osman9bfd5952020-02-05 10:51:44 -050099 sk_sp<SkData> fInputs;
Ethan Nicholas00543112018-07-31 09:44:36 -0400100
Brian Osman3b1e4c22019-08-12 15:12:14 -0400101 GrCoordTransform fCoordTransform;
102
Ethan Nicholas00543112018-07-31 09:44:36 -0400103 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
104
105 typedef GrFragmentProcessor INHERITED;
106
Ethan Nicholasce008112018-08-30 09:19:50 -0400107 friend class GrGLSLSkSLFP;
108
Ethan Nicholas00543112018-07-31 09:44:36 -0400109 friend class GrSkSLFPFactory;
110};
111
Ethan Nicholas00543112018-07-31 09:44:36 -0400112#endif