2019-12-16 14:17:25 +00:00
|
|
|
/*
|
|
|
|
* 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 SkRuntimeEffect_DEFINED
|
|
|
|
#define SkRuntimeEffect_DEFINED
|
|
|
|
|
2020-04-15 18:18:13 +00:00
|
|
|
#include "include/core/SkData.h"
|
2020-06-18 17:40:26 +00:00
|
|
|
#include "include/core/SkMatrix.h"
|
2019-12-16 14:17:25 +00:00
|
|
|
#include "include/core/SkString.h"
|
2020-07-20 15:18:23 +00:00
|
|
|
#include "include/private/GrTypesPriv.h"
|
2020-06-30 17:39:35 +00:00
|
|
|
#include "include/private/SkSLSampleUsage.h"
|
2019-12-16 14:17:25 +00:00
|
|
|
|
2020-06-18 17:40:26 +00:00
|
|
|
#include <string>
|
2019-12-16 14:17:25 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2019-12-30 20:02:30 +00:00
|
|
|
#if SK_SUPPORT_GPU
|
2020-03-06 20:23:54 +00:00
|
|
|
#include "include/gpu/GrContextOptions.h"
|
2019-12-30 20:02:30 +00:00
|
|
|
#endif
|
|
|
|
|
2020-01-02 13:03:40 +00:00
|
|
|
class SkColorFilter;
|
2019-12-26 13:43:05 +00:00
|
|
|
class SkShader;
|
2019-12-16 14:17:25 +00:00
|
|
|
|
|
|
|
namespace SkSL {
|
2020-12-02 16:12:51 +00:00
|
|
|
class FunctionDefinition;
|
2019-12-30 20:02:30 +00:00
|
|
|
struct PipelineStageArgs;
|
2019-12-16 14:17:25 +00:00
|
|
|
struct Program;
|
2020-02-21 18:43:49 +00:00
|
|
|
class SharedCompiler;
|
2020-08-06 18:11:56 +00:00
|
|
|
} // namespace SkSL
|
2019-12-16 14:17:25 +00:00
|
|
|
|
2020-01-02 16:55:24 +00:00
|
|
|
/*
|
|
|
|
* SkRuntimeEffect supports creating custom SkShader and SkColorFilter objects using Skia's SkSL
|
|
|
|
* shading language.
|
2020-04-15 18:18:13 +00:00
|
|
|
*
|
|
|
|
* NOTE: This API is experimental and subject to change.
|
2020-01-02 16:55:24 +00:00
|
|
|
*/
|
|
|
|
class SK_API SkRuntimeEffect : public SkRefCnt {
|
2019-12-16 14:17:25 +00:00
|
|
|
public:
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
struct Uniform {
|
2019-12-18 16:23:12 +00:00
|
|
|
enum class Type {
|
|
|
|
kFloat,
|
|
|
|
kFloat2,
|
|
|
|
kFloat3,
|
|
|
|
kFloat4,
|
|
|
|
kFloat2x2,
|
|
|
|
kFloat3x3,
|
|
|
|
kFloat4x4,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum Flags {
|
2020-04-15 18:18:13 +00:00
|
|
|
kArray_Flag = 0x1,
|
|
|
|
kMarker_Flag = 0x2,
|
|
|
|
kMarkerNormals_Flag = 0x4,
|
2020-04-30 21:12:03 +00:00
|
|
|
kSRGBUnpremul_Flag = 0x8,
|
2019-12-18 16:23:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
SkString fName;
|
|
|
|
size_t fOffset;
|
|
|
|
Type fType;
|
2020-07-20 15:18:23 +00:00
|
|
|
GrSLType fGPUType;
|
2019-12-18 16:23:12 +00:00
|
|
|
int fCount;
|
|
|
|
uint32_t fFlags;
|
2020-04-15 18:18:13 +00:00
|
|
|
uint32_t fMarker;
|
2019-12-18 16:23:12 +00:00
|
|
|
|
|
|
|
bool isArray() const { return SkToBool(fFlags & kArray_Flag); }
|
|
|
|
size_t sizeInBytes() const;
|
|
|
|
};
|
|
|
|
|
2020-03-23 14:44:12 +00:00
|
|
|
struct Varying {
|
|
|
|
SkString fName;
|
|
|
|
int fWidth; // 1 - 4 (floats)
|
|
|
|
};
|
|
|
|
|
2019-12-19 20:44:56 +00:00
|
|
|
// [Effect, ErrorText]
|
|
|
|
// If successful, Effect != nullptr, otherwise, ErrorText contains the reason for failure.
|
|
|
|
using EffectResult = std::tuple<sk_sp<SkRuntimeEffect>, SkString>;
|
|
|
|
static EffectResult Make(SkString sksl);
|
2019-12-16 14:17:25 +00:00
|
|
|
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
sk_sp<SkShader> makeShader(sk_sp<SkData> uniforms,
|
2020-04-15 18:18:13 +00:00
|
|
|
sk_sp<SkShader> children[],
|
|
|
|
size_t childCount,
|
|
|
|
const SkMatrix* localMatrix,
|
|
|
|
bool isOpaque);
|
2019-12-26 13:43:05 +00:00
|
|
|
|
2021-01-23 16:41:54 +00:00
|
|
|
sk_sp<SkImage> makeImage(GrRecordingContext*,
|
|
|
|
sk_sp<SkData> uniforms,
|
|
|
|
sk_sp<SkShader> children[],
|
|
|
|
size_t childCount,
|
|
|
|
const SkMatrix* localMatrix,
|
|
|
|
SkImageInfo resultInfo,
|
|
|
|
bool mipmapped);
|
|
|
|
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> uniforms);
|
|
|
|
sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> uniforms,
|
2020-08-06 14:53:12 +00:00
|
|
|
sk_sp<SkColorFilter> children[],
|
|
|
|
size_t childCount);
|
2020-01-02 13:03:40 +00:00
|
|
|
|
2019-12-16 14:17:25 +00:00
|
|
|
const SkString& source() const { return fSkSL; }
|
2020-01-08 18:19:58 +00:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
class ConstIterable {
|
|
|
|
public:
|
|
|
|
ConstIterable(const std::vector<T>& vec) : fVec(vec) {}
|
|
|
|
|
|
|
|
using const_iterator = typename std::vector<T>::const_iterator;
|
|
|
|
|
|
|
|
const_iterator begin() const { return fVec.begin(); }
|
|
|
|
const_iterator end() const { return fVec.end(); }
|
|
|
|
size_t count() const { return fVec.size(); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
const std::vector<T>& fVec;
|
|
|
|
};
|
|
|
|
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
// Combined size of all 'uniform' variables. When calling makeColorFilter or makeShader,
|
|
|
|
// provide an SkData of this size, containing values for all of those variables.
|
|
|
|
size_t uniformSize() const;
|
2020-01-10 15:05:24 +00:00
|
|
|
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
ConstIterable<Uniform> uniforms() const { return ConstIterable<Uniform>(fUniforms); }
|
2020-01-08 18:19:58 +00:00
|
|
|
ConstIterable<SkString> children() const { return ConstIterable<SkString>(fChildren); }
|
2020-03-23 14:44:12 +00:00
|
|
|
ConstIterable<Varying> varyings() const { return ConstIterable<Varying>(fVaryings); }
|
2019-12-16 14:17:25 +00:00
|
|
|
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
// Returns pointer to the named uniform variable's description, or nullptr if not found
|
|
|
|
const Uniform* findUniform(const char* name) const;
|
2020-04-15 18:18:13 +00:00
|
|
|
|
|
|
|
// Returns index of the named child, or -1 if not found
|
|
|
|
int findChild(const char* name) const;
|
|
|
|
|
|
|
|
static void RegisterFlattenables();
|
2020-07-21 21:03:56 +00:00
|
|
|
~SkRuntimeEffect() override;
|
2020-04-15 18:18:13 +00:00
|
|
|
|
|
|
|
private:
|
2020-06-18 17:40:26 +00:00
|
|
|
SkRuntimeEffect(SkString sksl,
|
|
|
|
std::unique_ptr<SkSL::Program> baseProgram,
|
2020-12-02 16:12:51 +00:00
|
|
|
const SkSL::FunctionDefinition& main,
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
std::vector<Uniform>&& uniforms,
|
2020-06-18 17:40:26 +00:00
|
|
|
std::vector<SkString>&& children,
|
2020-06-30 17:39:35 +00:00
|
|
|
std::vector<SkSL::SampleUsage>&& sampleUsages,
|
2020-06-18 17:40:26 +00:00
|
|
|
std::vector<Varying>&& varyings,
|
2020-08-05 20:48:58 +00:00
|
|
|
bool usesSampleCoords,
|
|
|
|
bool allowColorFilter);
|
2020-04-15 18:18:13 +00:00
|
|
|
|
2020-08-31 18:57:58 +00:00
|
|
|
uint32_t hash() const { return fHash; }
|
|
|
|
bool usesSampleCoords() const { return fUsesSampleCoords; }
|
|
|
|
|
2019-12-16 14:17:25 +00:00
|
|
|
#if SK_SUPPORT_GPU
|
2020-06-18 17:40:26 +00:00
|
|
|
friend class GrSkSLFP; // toPipelineStage
|
2020-06-30 17:39:35 +00:00
|
|
|
friend class GrGLSLSkSLFP; // fSampleUsages
|
2020-04-15 18:18:13 +00:00
|
|
|
|
2020-11-02 17:26:22 +00:00
|
|
|
bool toPipelineStage(GrContextOptions::ShaderErrorHandler* errorHandler,
|
2019-12-30 20:02:30 +00:00
|
|
|
SkSL::PipelineStageArgs* outArgs);
|
2019-12-16 14:17:25 +00:00
|
|
|
#endif
|
|
|
|
|
2020-12-02 16:12:51 +00:00
|
|
|
friend class SkRTShader; // fBaseProgram, fMain
|
2020-04-15 18:18:13 +00:00
|
|
|
friend class SkRuntimeColorFilter; //
|
|
|
|
|
2020-02-05 16:37:08 +00:00
|
|
|
uint32_t fHash;
|
2019-12-16 14:17:25 +00:00
|
|
|
SkString fSkSL;
|
|
|
|
|
|
|
|
std::unique_ptr<SkSL::Program> fBaseProgram;
|
2020-12-02 16:12:51 +00:00
|
|
|
const SkSL::FunctionDefinition& fMain;
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
std::vector<Uniform> fUniforms;
|
2019-12-18 20:44:27 +00:00
|
|
|
std::vector<SkString> fChildren;
|
2020-06-30 17:39:35 +00:00
|
|
|
std::vector<SkSL::SampleUsage> fSampleUsages;
|
2020-03-23 14:44:12 +00:00
|
|
|
std::vector<Varying> fVaryings;
|
2020-01-10 15:05:24 +00:00
|
|
|
|
2020-08-05 20:48:58 +00:00
|
|
|
bool fUsesSampleCoords;
|
|
|
|
bool fAllowColorFilter;
|
2019-12-16 14:17:25 +00:00
|
|
|
};
|
|
|
|
|
2020-04-15 18:18:13 +00:00
|
|
|
/**
|
|
|
|
* SkRuntimeShaderBuilder is a utility to simplify creating SkShader objects from SkRuntimeEffects.
|
|
|
|
*
|
|
|
|
* NOTE: Like SkRuntimeEffect, this API is experimental and subject to change!
|
|
|
|
*
|
|
|
|
* Given an SkRuntimeEffect, the SkRuntimeShaderBuilder manages creating an input data block and
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
* provides named access to the 'uniform' variables in that block, as well as named access
|
2020-04-15 18:18:13 +00:00
|
|
|
* to a list of child shader slots. Usage:
|
|
|
|
*
|
|
|
|
* sk_sp<SkRuntimeEffect> effect = ...;
|
|
|
|
* SkRuntimeShaderBuilder builder(effect);
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
* builder.uniform("some_uniform_float") = 3.14f;
|
|
|
|
* builder.uniform("some_uniform_matrix") = SkM44::Rotate(...);
|
2020-08-27 14:51:22 +00:00
|
|
|
* builder.child("some_child_effect") = mySkImage->makeShader(...);
|
2020-04-15 18:18:13 +00:00
|
|
|
* ...
|
|
|
|
* sk_sp<SkShader> shader = builder.makeShader(nullptr, false);
|
|
|
|
*
|
|
|
|
* Note that SkRuntimeShaderBuilder is built entirely on the public API of SkRuntimeEffect,
|
|
|
|
* so can be used as-is or serve as inspiration for other interfaces or binding techniques.
|
|
|
|
*/
|
2020-08-27 14:51:22 +00:00
|
|
|
class SkRuntimeShaderBuilder {
|
|
|
|
public:
|
2020-04-15 18:18:13 +00:00
|
|
|
SkRuntimeShaderBuilder(sk_sp<SkRuntimeEffect>);
|
|
|
|
~SkRuntimeShaderBuilder();
|
|
|
|
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
struct BuilderUniform {
|
2020-04-15 18:18:13 +00:00
|
|
|
// Copy 'val' to this variable. No type conversion is performed - 'val' must be same
|
|
|
|
// size as expected by the effect. Information about the variable can be queried by
|
|
|
|
// looking at fVar. If the size is incorrect, no copy will be performed, and debug
|
|
|
|
// builds will abort. If this is the result of querying a missing variable, fVar will
|
|
|
|
// be nullptr, and assigning will also do nothing (and abort in debug builds).
|
|
|
|
template <typename T>
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
std::enable_if_t<std::is_trivially_copyable<T>::value, BuilderUniform&> operator=(
|
2020-04-15 18:18:13 +00:00
|
|
|
const T& val) {
|
|
|
|
if (!fVar) {
|
|
|
|
SkDEBUGFAIL("Assigning to missing variable");
|
|
|
|
} else if (sizeof(val) != fVar->sizeInBytes()) {
|
|
|
|
SkDEBUGFAIL("Incorrect value size");
|
|
|
|
} else {
|
2020-08-27 14:51:22 +00:00
|
|
|
memcpy(SkTAddOffset<void>(fOwner->writableUniformData(), fVar->fOffset),
|
|
|
|
&val, sizeof(val));
|
2020-04-15 18:18:13 +00:00
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
BuilderUniform& operator=(const SkMatrix& val) {
|
2020-06-18 17:40:26 +00:00
|
|
|
if (!fVar) {
|
|
|
|
SkDEBUGFAIL("Assigning to missing variable");
|
|
|
|
} else if (fVar->sizeInBytes() != 9 * sizeof(float)) {
|
|
|
|
SkDEBUGFAIL("Incorrect value size");
|
|
|
|
} else {
|
2020-08-27 14:51:22 +00:00
|
|
|
float* data = SkTAddOffset<float>(fOwner->writableUniformData(), fVar->fOffset);
|
2020-06-18 17:40:26 +00:00
|
|
|
data[0] = val.get(0); data[1] = val.get(3); data[2] = val.get(6);
|
|
|
|
data[3] = val.get(1); data[4] = val.get(4); data[5] = val.get(7);
|
|
|
|
data[6] = val.get(2); data[7] = val.get(5); data[8] = val.get(8);
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-01-14 13:30:52 +00:00
|
|
|
template <typename T>
|
|
|
|
bool set(const T val[], const int count) {
|
|
|
|
static_assert(std::is_trivially_copyable<T>::value, "Value must be trivial copyable");
|
|
|
|
if (!fVar) {
|
|
|
|
SkDEBUGFAIL("Assigning to missing variable");
|
|
|
|
return false;
|
|
|
|
} else if (sizeof(T) * count != fVar->sizeInBytes()) {
|
|
|
|
SkDEBUGFAIL("Incorrect value size");
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
memcpy(SkTAddOffset<void>(fOwner->writableUniformData(), fVar->fOffset),
|
|
|
|
val, sizeof(T) * count);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
SkRuntimeShaderBuilder* fOwner;
|
|
|
|
const SkRuntimeEffect::Uniform* fVar; // nullptr if the variable was not found
|
2020-04-15 18:18:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct BuilderChild {
|
|
|
|
BuilderChild& operator=(const sk_sp<SkShader>& val);
|
|
|
|
|
|
|
|
SkRuntimeShaderBuilder* fOwner;
|
|
|
|
int fIndex; // -1 if the child was not found
|
|
|
|
};
|
|
|
|
|
2020-08-27 14:51:22 +00:00
|
|
|
const SkRuntimeEffect* effect() const { return fEffect.get(); }
|
|
|
|
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
BuilderUniform uniform(const char* name) { return { this, fEffect->findUniform(name) }; }
|
2020-04-15 18:18:13 +00:00
|
|
|
BuilderChild child(const char* name) { return { this, fEffect->findChild(name) }; }
|
|
|
|
|
|
|
|
sk_sp<SkShader> makeShader(const SkMatrix* localMatrix, bool isOpaque);
|
2021-01-23 16:41:54 +00:00
|
|
|
sk_sp<SkImage> makeImage(GrRecordingContext*,
|
|
|
|
const SkMatrix* localMatrix,
|
|
|
|
SkImageInfo resultInfo,
|
|
|
|
bool mipmapped);
|
2020-04-15 18:18:13 +00:00
|
|
|
|
2020-08-27 14:51:22 +00:00
|
|
|
private:
|
|
|
|
void* writableUniformData();
|
|
|
|
|
2020-04-15 18:18:13 +00:00
|
|
|
sk_sp<SkRuntimeEffect> fEffect;
|
Remove 'in' variables from SkRuntimeEffect
Runtime effects previously allowed two kinds of global input variables:
'in' variables could be bool, int, or float. 'uniform' could be float,
vector, or matrix. Uniform variables worked like you'd expect, but 'in'
variables were baked into the program statically. There was a large
amount of machinery to make this work, and it meant that 'in' variables
needed to have values before we could make decisions about program
caching, and before we could catch some errors. It was also essentially
syntactic sugar over the client just inserting the value into their SkSL
as a string. Finally: No one was using the feature.
To simplify the mental model, and make the API much more predictable,
this CL removes 'in' variables entirely. We no longer need to
"specialize" runtime effect programs, which means we can catch more
errors up front (those not detected until optimization). All of the API
that referred to "inputs" (the previous term that unified 'in' and
'uniform') now just refers to "uniforms".
Bug: skia:10593
Change-Id: I971f620d868b259e652b3114f0b497c2620f4b0c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/309050
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2020-08-10 18:26:16 +00:00
|
|
|
sk_sp<SkData> fUniforms;
|
2020-04-15 18:18:13 +00:00
|
|
|
std::vector<sk_sp<SkShader>> fChildren;
|
|
|
|
};
|
|
|
|
|
2019-12-16 14:17:25 +00:00
|
|
|
#endif
|