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
|
|
|
|
|
|
|
|
#include "include/core/SkString.h"
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
2019-12-30 20:02:30 +00:00
|
|
|
#if SK_SUPPORT_GPU
|
|
|
|
#include "include/private/GrTypesPriv.h"
|
|
|
|
#endif
|
|
|
|
|
2019-12-16 14:17:25 +00:00
|
|
|
class GrShaderCaps;
|
2020-01-02 13:03:40 +00:00
|
|
|
class SkColorFilter;
|
2019-12-26 13:43:05 +00:00
|
|
|
class SkMatrix;
|
|
|
|
class SkShader;
|
2019-12-16 14:17:25 +00:00
|
|
|
|
|
|
|
namespace SkSL {
|
|
|
|
class ByteCode;
|
2019-12-30 20:02:30 +00:00
|
|
|
class Compiler;
|
|
|
|
struct PipelineStageArgs;
|
2019-12-16 14:17:25 +00:00
|
|
|
struct Program;
|
|
|
|
}
|
|
|
|
|
2020-01-02 16:55:24 +00:00
|
|
|
/*
|
|
|
|
* SkRuntimeEffect supports creating custom SkShader and SkColorFilter objects using Skia's SkSL
|
|
|
|
* shading language.
|
|
|
|
* *
|
|
|
|
* This API is experimental and subject to change.
|
|
|
|
*/
|
|
|
|
class SK_API SkRuntimeEffect : public SkRefCnt {
|
2019-12-16 14:17:25 +00:00
|
|
|
public:
|
2019-12-18 16:23:12 +00:00
|
|
|
struct Variable {
|
|
|
|
enum class Qualifier {
|
|
|
|
kUniform,
|
|
|
|
kIn,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class Type {
|
|
|
|
kBool,
|
|
|
|
kInt,
|
|
|
|
kFloat,
|
|
|
|
kFloat2,
|
|
|
|
kFloat3,
|
|
|
|
kFloat4,
|
|
|
|
kFloat2x2,
|
|
|
|
kFloat3x3,
|
|
|
|
kFloat4x4,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum Flags {
|
|
|
|
kArray_Flag = 0x1,
|
|
|
|
};
|
|
|
|
|
|
|
|
SkString fName;
|
|
|
|
size_t fOffset;
|
|
|
|
Qualifier fQualifier;
|
|
|
|
Type fType;
|
|
|
|
int fCount;
|
|
|
|
uint32_t fFlags;
|
|
|
|
|
|
|
|
#if SK_SUPPORT_GPU
|
|
|
|
GrSLType fGPUType;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool isArray() const { return SkToBool(fFlags & kArray_Flag); }
|
|
|
|
size_t sizeInBytes() const;
|
|
|
|
};
|
|
|
|
|
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
|
|
|
|
2019-12-26 13:43:05 +00:00
|
|
|
sk_sp<SkShader> makeShader(sk_sp<SkData> inputs, sk_sp<SkShader> children[], size_t childCount,
|
|
|
|
const SkMatrix* localMatrix, bool isOpaque);
|
|
|
|
|
2020-01-02 13:03:40 +00:00
|
|
|
sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> inputs);
|
|
|
|
|
2019-12-16 14:17:25 +00:00
|
|
|
const SkString& source() const { return fSkSL; }
|
|
|
|
int index() const { return fIndex; }
|
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;
|
|
|
|
};
|
|
|
|
|
2020-01-10 15:05:24 +00:00
|
|
|
// Combined size of all 'in' and 'uniform' variables. When calling makeColorFilter or
|
|
|
|
// makeShader, provide an SkData of this size, containing values for all of those variables.
|
2019-12-18 16:23:12 +00:00
|
|
|
size_t inputSize() const;
|
2020-01-10 15:05:24 +00:00
|
|
|
|
|
|
|
// Combined size of just the 'uniform' variables.
|
|
|
|
size_t uniformSize() const { return fUniformSize; }
|
|
|
|
|
2020-01-08 18:19:58 +00:00
|
|
|
ConstIterable<Variable> inputs() const { return ConstIterable<Variable>(fInAndUniformVars); }
|
|
|
|
ConstIterable<SkString> children() const { return ConstIterable<SkString>(fChildren); }
|
2019-12-16 14:17:25 +00:00
|
|
|
|
|
|
|
#if SK_SUPPORT_GPU
|
|
|
|
// This re-compiles the program from scratch, using the supplied shader caps.
|
|
|
|
// This is necessary to get the correct values of settings.
|
2019-12-18 16:23:12 +00:00
|
|
|
bool toPipelineStage(const void* inputs, const GrShaderCaps* shaderCaps,
|
2019-12-30 20:02:30 +00:00
|
|
|
SkSL::PipelineStageArgs* outArgs);
|
2019-12-16 14:17:25 +00:00
|
|
|
#endif
|
|
|
|
|
2019-12-19 20:44:56 +00:00
|
|
|
// [ByteCode, ErrorText]
|
|
|
|
// If successful, ByteCode != nullptr, otherwise, ErrorText contains the reason for failure.
|
|
|
|
using ByteCodeResult = std::tuple<std::unique_ptr<SkSL::ByteCode>, SkString>;
|
|
|
|
|
2020-01-10 15:05:24 +00:00
|
|
|
ByteCodeResult toByteCode(const void* inputs);
|
2019-12-16 14:17:25 +00:00
|
|
|
|
|
|
|
private:
|
2019-12-19 20:44:56 +00:00
|
|
|
SkRuntimeEffect(SkString sksl, std::unique_ptr<SkSL::Compiler> compiler,
|
2019-12-30 18:44:01 +00:00
|
|
|
std::unique_ptr<SkSL::Program> baseProgram,
|
2020-01-10 15:05:24 +00:00
|
|
|
std::vector<Variable>&& inAndUniformVars, std::vector<SkString>&& children,
|
|
|
|
size_t uniformSize);
|
|
|
|
|
|
|
|
using SpecializeResult = std::tuple<std::unique_ptr<SkSL::Program>, SkString>;
|
|
|
|
SpecializeResult specialize(SkSL::Program& baseProgram, const void* inputs);
|
2019-12-16 14:17:25 +00:00
|
|
|
|
|
|
|
int fIndex;
|
|
|
|
SkString fSkSL;
|
|
|
|
|
2019-12-19 20:44:56 +00:00
|
|
|
std::unique_ptr<SkSL::Compiler> fCompiler;
|
2019-12-16 14:17:25 +00:00
|
|
|
std::unique_ptr<SkSL::Program> fBaseProgram;
|
2019-12-18 16:23:12 +00:00
|
|
|
std::vector<Variable> fInAndUniformVars;
|
2019-12-18 20:44:27 +00:00
|
|
|
std::vector<SkString> fChildren;
|
2020-01-10 15:05:24 +00:00
|
|
|
|
|
|
|
size_t fUniformSize;
|
2019-12-16 14:17:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|