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
|
|
|
|
|
2021-05-05 12:24:03 +00:00
|
|
|
#include "include/core/SkColorFilter.h"
|
2020-04-15 18:18:13 +00:00
|
|
|
#include "include/core/SkData.h"
|
2021-02-18 20:51:20 +00:00
|
|
|
#include "include/core/SkImageInfo.h"
|
2020-06-18 17:40:26 +00:00
|
|
|
#include "include/core/SkMatrix.h"
|
2021-03-23 21:04:41 +00:00
|
|
|
#include "include/core/SkShader.h"
|
2021-05-05 12:24:03 +00:00
|
|
|
#include "include/core/SkSpan.h"
|
2019-12-16 14:17:25 +00:00
|
|
|
#include "include/core/SkString.h"
|
2021-03-11 17:33:38 +00:00
|
|
|
#include "include/private/SkOnce.h"
|
2020-06-30 17:39:35 +00:00
|
|
|
#include "include/private/SkSLSampleUsage.h"
|
2019-12-16 14:17:25 +00:00
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
2021-02-18 20:51:20 +00:00
|
|
|
class GrRecordingContext;
|
2021-05-12 20:53:19 +00:00
|
|
|
class SkFilterColorProgram;
|
2021-02-18 20:51:20 +00:00
|
|
|
class SkImage;
|
2019-12-16 14:17:25 +00:00
|
|
|
|
|
|
|
namespace SkSL {
|
2020-12-02 16:12:51 +00:00
|
|
|
class FunctionDefinition;
|
2019-12-16 14:17:25 +00:00
|
|
|
struct Program;
|
2021-04-12 13:49:20 +00:00
|
|
|
enum class ProgramKind : int8_t;
|
2020-08-06 18:11:56 +00:00
|
|
|
} // namespace SkSL
|
2019-12-16 14:17:25 +00:00
|
|
|
|
2021-03-11 17:33:38 +00:00
|
|
|
namespace skvm {
|
|
|
|
class Program;
|
|
|
|
} // namespace skvm
|
|
|
|
|
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:
|
2021-05-05 12:24:03 +00:00
|
|
|
// Reflected description of a uniform variable in the effect's SkSL
|
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,
|
2021-04-01 13:56:07 +00:00
|
|
|
kInt,
|
|
|
|
kInt2,
|
|
|
|
kInt3,
|
|
|
|
kInt4,
|
2019-12-18 16:23:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum Flags {
|
2020-04-15 18:18:13 +00:00
|
|
|
kArray_Flag = 0x1,
|
2021-04-19 17:50:58 +00:00
|
|
|
kSRGBUnpremul_Flag = 0x2,
|
2019-12-18 16:23:12 +00:00
|
|
|
};
|
|
|
|
|
2021-02-03 19:48:41 +00:00
|
|
|
SkString name;
|
|
|
|
size_t offset;
|
|
|
|
Type type;
|
|
|
|
int count;
|
|
|
|
uint32_t flags;
|
|
|
|
|
|
|
|
bool isArray() const { return SkToBool(this->flags & kArray_Flag); }
|
2019-12-18 16:23:12 +00:00
|
|
|
size_t sizeInBytes() const;
|
|
|
|
};
|
|
|
|
|
2021-05-05 12:24:03 +00:00
|
|
|
// Reflected description of a uniform child (shader or colorFilter) in the effect's SkSL
|
Reland "Better first-class shader & color filter support in runtime effects"
This is a reland of adadb95a9f1ef21ccc5264c7d0bdc83b56cf91e9
... adds a temporary workaround for some Android framework code.
Original change's description:
> Better first-class shader & color filter support in runtime effects
>
> This does a few things, because they're all intertwined:
>
> 1) SkRuntimeEffect's API now includes details about children (which Skia
> stage was declared, not just the name). The factories verify that the
> declared types in the SkSL match up with the C++ types being passed.
> Today, we still only support adding children of the same type, so the
> checks are simple. Once we allow mixing types, we'll be testing the
> declared type against the actual C++ type supplied for each slot.
> 2) Adds sample variants that supply the input color to the child. This
> is now the only way to invoke a colorFilter child. Internally, we
> support passing a color when invoking a child shader, but I'm not
> exposing that. It's not clearly part of the semantics of the Skia
> pipeline, and is almost never useful. It also exposes users to
> several inconsistencies (skbug.com/11942).
> 3) Because of #2, it's possible that we can't compute a reusable program
> to filter individual colors. In that case, we don't set the constant
> output for constant input optimization, and filterColor4f falls back
> to the slower base-class implementation.
>
> Bug: skia:11813 skia:11942
> Change-Id: I06c41e1b35056e486f3163a72acf6b9535d7fed4
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401917
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
Bug: skia:11813 skia:11942
Change-Id: I2c31b147ed86fa8c4dddefb7066bc1d07fe0d285
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404637
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-04-21 13:57:19 +00:00
|
|
|
struct Child {
|
|
|
|
enum class Type {
|
|
|
|
kShader,
|
|
|
|
kColorFilter,
|
|
|
|
};
|
|
|
|
|
|
|
|
SkString name;
|
|
|
|
Type type;
|
|
|
|
int index;
|
|
|
|
};
|
|
|
|
|
2021-02-03 16:15:20 +00:00
|
|
|
struct Options {
|
2021-03-23 13:25:33 +00:00
|
|
|
// For testing purposes, completely disable the inliner. (Normally, Runtime Effects don't
|
|
|
|
// run the inliner directly, but they still get an inlining pass once they are painted.)
|
|
|
|
bool forceNoInline = false;
|
2021-04-28 19:14:09 +00:00
|
|
|
// For testing purposes only; only honored when GR_TEST_UTILS is enabled. This flag lifts
|
|
|
|
// the ES2 restrictions on Runtime Effects that are gated by the `strictES2Mode` check.
|
|
|
|
// Be aware that the software renderer and pipeline-stage effect are still largely
|
|
|
|
// ES3-unaware and can still fail or crash if post-ES2 features are used.
|
|
|
|
bool enforceES2Restrictions = true;
|
2021-02-03 16:15:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// If the effect is compiled successfully, `effect` will be non-null.
|
|
|
|
// Otherwise, `errorText` will contain the reason for failure.
|
|
|
|
struct Result {
|
|
|
|
sk_sp<SkRuntimeEffect> effect;
|
|
|
|
SkString errorText;
|
|
|
|
};
|
|
|
|
|
2021-04-12 13:49:20 +00:00
|
|
|
// MakeForColorFilter and MakeForShader verify that the SkSL code is valid for those stages of
|
|
|
|
// the Skia pipeline. In all of the signatures described below, color parameters and return
|
|
|
|
// values are flexible. They are listed as being 'vec4', but they can also be 'half4' or
|
|
|
|
// 'float4'. ('vec4' is an alias for 'float4').
|
|
|
|
|
|
|
|
// Color filter SkSL requires an entry point that looks like:
|
|
|
|
// vec4 main(vec4 inColor) { ... }
|
|
|
|
static Result MakeForColorFilter(SkString sksl, const Options&);
|
|
|
|
|
|
|
|
// Shader SkSL requires an entry point that looks like:
|
|
|
|
// vec4 main(vec2 inCoords) { ... }
|
|
|
|
// -or-
|
|
|
|
// vec4 main(vec2 inCoords, vec4 inColor) { ... }
|
|
|
|
//
|
|
|
|
// Most shaders don't use the input color, so that parameter is optional.
|
|
|
|
static Result MakeForShader(SkString sksl, const Options&);
|
|
|
|
|
2021-02-11 22:40:03 +00:00
|
|
|
// We can't use a default argument for `options` due to a bug in Clang.
|
|
|
|
// https://bugs.llvm.org/show_bug.cgi?id=36684
|
2021-04-12 13:49:20 +00:00
|
|
|
static Result MakeForColorFilter(SkString sksl) {
|
|
|
|
return MakeForColorFilter(std::move(sksl), Options{});
|
|
|
|
}
|
|
|
|
static Result MakeForShader(SkString sksl) {
|
|
|
|
return MakeForShader(std::move(sksl), Options{});
|
|
|
|
}
|
2019-12-16 14:17:25 +00:00
|
|
|
|
2021-04-16 18:54:43 +00:00
|
|
|
static Result MakeForColorFilter(std::unique_ptr<SkSL::Program> program);
|
|
|
|
|
|
|
|
static Result MakeForShader(std::unique_ptr<SkSL::Program> program);
|
|
|
|
|
2021-05-05 12:24:03 +00:00
|
|
|
// Object that allows passing either an SkShader or SkColorFilter as a child
|
|
|
|
struct ChildPtr {
|
|
|
|
ChildPtr(sk_sp<SkShader> s) : shader(std::move(s)) {}
|
|
|
|
ChildPtr(sk_sp<SkColorFilter> cf) : colorFilter(std::move(cf)) {}
|
|
|
|
sk_sp<SkShader> shader;
|
|
|
|
sk_sp<SkColorFilter> colorFilter;
|
|
|
|
};
|
|
|
|
|
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,
|
2021-03-23 21:04:41 +00:00
|
|
|
bool isOpaque) const;
|
2021-05-05 12:24:03 +00:00
|
|
|
sk_sp<SkShader> makeShader(sk_sp<SkData> uniforms,
|
|
|
|
SkSpan<ChildPtr> children,
|
|
|
|
const SkMatrix* localMatrix,
|
|
|
|
bool isOpaque) const;
|
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,
|
2021-03-23 21:04:41 +00:00
|
|
|
bool mipmapped) const;
|
2021-01-23 16:41:54 +00:00
|
|
|
|
2021-03-23 21:04:41 +00:00
|
|
|
sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> uniforms) const;
|
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,
|
2020-08-06 14:53:12 +00:00
|
|
|
sk_sp<SkColorFilter> children[],
|
2021-03-23 21:04:41 +00:00
|
|
|
size_t childCount) const;
|
2021-05-05 12:24:03 +00:00
|
|
|
sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> uniforms,
|
|
|
|
SkSpan<ChildPtr> children) const;
|
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); }
|
Reland "Better first-class shader & color filter support in runtime effects"
This is a reland of adadb95a9f1ef21ccc5264c7d0bdc83b56cf91e9
... adds a temporary workaround for some Android framework code.
Original change's description:
> Better first-class shader & color filter support in runtime effects
>
> This does a few things, because they're all intertwined:
>
> 1) SkRuntimeEffect's API now includes details about children (which Skia
> stage was declared, not just the name). The factories verify that the
> declared types in the SkSL match up with the C++ types being passed.
> Today, we still only support adding children of the same type, so the
> checks are simple. Once we allow mixing types, we'll be testing the
> declared type against the actual C++ type supplied for each slot.
> 2) Adds sample variants that supply the input color to the child. This
> is now the only way to invoke a colorFilter child. Internally, we
> support passing a color when invoking a child shader, but I'm not
> exposing that. It's not clearly part of the semantics of the Skia
> pipeline, and is almost never useful. It also exposes users to
> several inconsistencies (skbug.com/11942).
> 3) Because of #2, it's possible that we can't compute a reusable program
> to filter individual colors. In that case, we don't set the constant
> output for constant input optimization, and filterColor4f falls back
> to the slower base-class implementation.
>
> Bug: skia:11813 skia:11942
> Change-Id: I06c41e1b35056e486f3163a72acf6b9535d7fed4
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401917
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
Bug: skia:11813 skia:11942
Change-Id: I2c31b147ed86fa8c4dddefb7066bc1d07fe0d285
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404637
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-04-21 13:57:19 +00:00
|
|
|
ConstIterable<Child> children() const { return ConstIterable<Child>(fChildren); }
|
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
|
|
|
|
Reland "Better first-class shader & color filter support in runtime effects"
This is a reland of adadb95a9f1ef21ccc5264c7d0bdc83b56cf91e9
... adds a temporary workaround for some Android framework code.
Original change's description:
> Better first-class shader & color filter support in runtime effects
>
> This does a few things, because they're all intertwined:
>
> 1) SkRuntimeEffect's API now includes details about children (which Skia
> stage was declared, not just the name). The factories verify that the
> declared types in the SkSL match up with the C++ types being passed.
> Today, we still only support adding children of the same type, so the
> checks are simple. Once we allow mixing types, we'll be testing the
> declared type against the actual C++ type supplied for each slot.
> 2) Adds sample variants that supply the input color to the child. This
> is now the only way to invoke a colorFilter child. Internally, we
> support passing a color when invoking a child shader, but I'm not
> exposing that. It's not clearly part of the semantics of the Skia
> pipeline, and is almost never useful. It also exposes users to
> several inconsistencies (skbug.com/11942).
> 3) Because of #2, it's possible that we can't compute a reusable program
> to filter individual colors. In that case, we don't set the constant
> output for constant input optimization, and filterColor4f falls back
> to the slower base-class implementation.
>
> Bug: skia:11813 skia:11942
> Change-Id: I06c41e1b35056e486f3163a72acf6b9535d7fed4
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401917
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
Bug: skia:11813 skia:11942
Change-Id: I2c31b147ed86fa8c4dddefb7066bc1d07fe0d285
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404637
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-04-21 13:57:19 +00:00
|
|
|
// Returns pointer to the named child's description, or nullptr if not found
|
|
|
|
const Child* findChild(const char* name) const;
|
2020-04-15 18:18:13 +00:00
|
|
|
|
|
|
|
static void RegisterFlattenables();
|
2020-07-21 21:03:56 +00:00
|
|
|
~SkRuntimeEffect() override;
|
2020-04-15 18:18:13 +00:00
|
|
|
|
|
|
|
private:
|
2021-04-12 13:49:20 +00:00
|
|
|
enum Flags {
|
|
|
|
kUsesSampleCoords_Flag = 0x1,
|
|
|
|
kAllowColorFilter_Flag = 0x2,
|
|
|
|
kAllowShader_Flag = 0x4,
|
2021-06-16 15:33:13 +00:00
|
|
|
kAllowBlender_Flag = 0x8,
|
2021-04-12 13:49:20 +00:00
|
|
|
};
|
|
|
|
|
2020-06-18 17:40:26 +00:00
|
|
|
SkRuntimeEffect(SkString sksl,
|
|
|
|
std::unique_ptr<SkSL::Program> baseProgram,
|
2021-03-23 13:14:58 +00:00
|
|
|
const Options& options,
|
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,
|
Reland "Better first-class shader & color filter support in runtime effects"
This is a reland of adadb95a9f1ef21ccc5264c7d0bdc83b56cf91e9
... adds a temporary workaround for some Android framework code.
Original change's description:
> Better first-class shader & color filter support in runtime effects
>
> This does a few things, because they're all intertwined:
>
> 1) SkRuntimeEffect's API now includes details about children (which Skia
> stage was declared, not just the name). The factories verify that the
> declared types in the SkSL match up with the C++ types being passed.
> Today, we still only support adding children of the same type, so the
> checks are simple. Once we allow mixing types, we'll be testing the
> declared type against the actual C++ type supplied for each slot.
> 2) Adds sample variants that supply the input color to the child. This
> is now the only way to invoke a colorFilter child. Internally, we
> support passing a color when invoking a child shader, but I'm not
> exposing that. It's not clearly part of the semantics of the Skia
> pipeline, and is almost never useful. It also exposes users to
> several inconsistencies (skbug.com/11942).
> 3) Because of #2, it's possible that we can't compute a reusable program
> to filter individual colors. In that case, we don't set the constant
> output for constant input optimization, and filterColor4f falls back
> to the slower base-class implementation.
>
> Bug: skia:11813 skia:11942
> Change-Id: I06c41e1b35056e486f3163a72acf6b9535d7fed4
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401917
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
Bug: skia:11813 skia:11942
Change-Id: I2c31b147ed86fa8c4dddefb7066bc1d07fe0d285
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404637
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-04-21 13:57:19 +00:00
|
|
|
std::vector<Child>&& children,
|
2020-06-30 17:39:35 +00:00
|
|
|
std::vector<SkSL::SampleUsage>&& sampleUsages,
|
2021-04-12 13:49:20 +00:00
|
|
|
uint32_t flags);
|
|
|
|
|
2021-04-16 18:54:43 +00:00
|
|
|
static Result Make(std::unique_ptr<SkSL::Program> program, SkSL::ProgramKind kind);
|
|
|
|
|
2021-04-12 13:49:20 +00:00
|
|
|
static Result Make(SkString sksl, const Options& options, SkSL::ProgramKind kind);
|
2020-04-15 18:18:13 +00:00
|
|
|
|
2021-04-16 18:54:43 +00:00
|
|
|
static Result Make(SkString sksl, std::unique_ptr<SkSL::Program> program,
|
|
|
|
const Options& options, SkSL::ProgramKind kind);
|
|
|
|
|
2020-08-31 18:57:58 +00:00
|
|
|
uint32_t hash() const { return fHash; }
|
2021-04-12 13:49:20 +00:00
|
|
|
bool usesSampleCoords() const { return (fFlags & kUsesSampleCoords_Flag); }
|
|
|
|
bool allowShader() const { return (fFlags & kAllowShader_Flag); }
|
|
|
|
bool allowColorFilter() const { return (fFlags & kAllowColorFilter_Flag); }
|
2021-06-16 15:33:13 +00:00
|
|
|
bool allowBlender() const { return (fFlags & kAllowBlender_Flag); }
|
2020-08-31 18:57:58 +00:00
|
|
|
|
2021-05-12 20:53:19 +00:00
|
|
|
const SkFilterColorProgram* getFilterColorProgram();
|
2021-03-22 15:44:03 +00:00
|
|
|
|
2019-12-16 14:17:25 +00:00
|
|
|
#if SK_SUPPORT_GPU
|
2021-04-28 13:41:06 +00:00
|
|
|
friend class GrSkSLFP; // fBaseProgram, fSampleUsages
|
|
|
|
friend class GrGLSLSkSLFP; //
|
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; //
|
|
|
|
|
2021-05-12 20:53:19 +00:00
|
|
|
friend class SkFilterColorProgram;
|
|
|
|
|
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;
|
Reland "Better first-class shader & color filter support in runtime effects"
This is a reland of adadb95a9f1ef21ccc5264c7d0bdc83b56cf91e9
... adds a temporary workaround for some Android framework code.
Original change's description:
> Better first-class shader & color filter support in runtime effects
>
> This does a few things, because they're all intertwined:
>
> 1) SkRuntimeEffect's API now includes details about children (which Skia
> stage was declared, not just the name). The factories verify that the
> declared types in the SkSL match up with the C++ types being passed.
> Today, we still only support adding children of the same type, so the
> checks are simple. Once we allow mixing types, we'll be testing the
> declared type against the actual C++ type supplied for each slot.
> 2) Adds sample variants that supply the input color to the child. This
> is now the only way to invoke a colorFilter child. Internally, we
> support passing a color when invoking a child shader, but I'm not
> exposing that. It's not clearly part of the semantics of the Skia
> pipeline, and is almost never useful. It also exposes users to
> several inconsistencies (skbug.com/11942).
> 3) Because of #2, it's possible that we can't compute a reusable program
> to filter individual colors. In that case, we don't set the constant
> output for constant input optimization, and filterColor4f falls back
> to the slower base-class implementation.
>
> Bug: skia:11813 skia:11942
> Change-Id: I06c41e1b35056e486f3163a72acf6b9535d7fed4
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401917
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
Bug: skia:11813 skia:11942
Change-Id: I2c31b147ed86fa8c4dddefb7066bc1d07fe0d285
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404637
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-04-21 13:57:19 +00:00
|
|
|
std::vector<Child> fChildren;
|
2020-06-30 17:39:35 +00:00
|
|
|
std::vector<SkSL::SampleUsage> fSampleUsages;
|
2020-01-10 15:05:24 +00:00
|
|
|
|
2021-05-12 20:53:19 +00:00
|
|
|
std::unique_ptr<SkFilterColorProgram> fFilterColorProgram;
|
2021-03-11 17:33:38 +00:00
|
|
|
|
2021-04-12 13:49:20 +00:00
|
|
|
uint32_t fFlags; // Flags
|
2019-12-16 14:17:25 +00:00
|
|
|
};
|
|
|
|
|
2021-03-23 21:04:41 +00:00
|
|
|
/** Base class for SkRuntimeShaderBuilder, defined below. */
|
|
|
|
template <typename Child> class SkRuntimeEffectBuilder {
|
2020-08-27 14:51:22 +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 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 {
|
2021-02-03 19:48:41 +00:00
|
|
|
memcpy(SkTAddOffset<void>(fOwner->writableUniformData(), fVar->offset),
|
2020-08-27 14:51:22 +00:00
|
|
|
&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 {
|
2021-02-03 19:48:41 +00:00
|
|
|
float* data = SkTAddOffset<float>(fOwner->writableUniformData(), fVar->offset);
|
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 {
|
2021-02-03 19:48:41 +00:00
|
|
|
memcpy(SkTAddOffset<void>(fOwner->writableUniformData(), fVar->offset),
|
2021-01-14 13:30:52 +00:00
|
|
|
val, sizeof(T) * count);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-03-23 21:04:41 +00:00
|
|
|
SkRuntimeEffectBuilder* fOwner;
|
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
|
|
|
const SkRuntimeEffect::Uniform* fVar; // nullptr if the variable was not found
|
2020-04-15 18:18:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct BuilderChild {
|
2021-03-23 21:04:41 +00:00
|
|
|
template <typename C> BuilderChild& operator=(C&& val) {
|
Reland "Better first-class shader & color filter support in runtime effects"
This is a reland of adadb95a9f1ef21ccc5264c7d0bdc83b56cf91e9
... adds a temporary workaround for some Android framework code.
Original change's description:
> Better first-class shader & color filter support in runtime effects
>
> This does a few things, because they're all intertwined:
>
> 1) SkRuntimeEffect's API now includes details about children (which Skia
> stage was declared, not just the name). The factories verify that the
> declared types in the SkSL match up with the C++ types being passed.
> Today, we still only support adding children of the same type, so the
> checks are simple. Once we allow mixing types, we'll be testing the
> declared type against the actual C++ type supplied for each slot.
> 2) Adds sample variants that supply the input color to the child. This
> is now the only way to invoke a colorFilter child. Internally, we
> support passing a color when invoking a child shader, but I'm not
> exposing that. It's not clearly part of the semantics of the Skia
> pipeline, and is almost never useful. It also exposes users to
> several inconsistencies (skbug.com/11942).
> 3) Because of #2, it's possible that we can't compute a reusable program
> to filter individual colors. In that case, we don't set the constant
> output for constant input optimization, and filterColor4f falls back
> to the slower base-class implementation.
>
> Bug: skia:11813 skia:11942
> Change-Id: I06c41e1b35056e486f3163a72acf6b9535d7fed4
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401917
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
Bug: skia:11813 skia:11942
Change-Id: I2c31b147ed86fa8c4dddefb7066bc1d07fe0d285
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404637
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-04-21 13:57:19 +00:00
|
|
|
// TODO(skbug:11813): Validate that the type of val lines up with the type of the child
|
|
|
|
// (SkShader vs. SkColorFilter).
|
|
|
|
if (!fChild) {
|
2021-03-23 21:04:41 +00:00
|
|
|
SkDEBUGFAIL("Assigning to missing child");
|
|
|
|
} else {
|
Reland "Better first-class shader & color filter support in runtime effects"
This is a reland of adadb95a9f1ef21ccc5264c7d0bdc83b56cf91e9
... adds a temporary workaround for some Android framework code.
Original change's description:
> Better first-class shader & color filter support in runtime effects
>
> This does a few things, because they're all intertwined:
>
> 1) SkRuntimeEffect's API now includes details about children (which Skia
> stage was declared, not just the name). The factories verify that the
> declared types in the SkSL match up with the C++ types being passed.
> Today, we still only support adding children of the same type, so the
> checks are simple. Once we allow mixing types, we'll be testing the
> declared type against the actual C++ type supplied for each slot.
> 2) Adds sample variants that supply the input color to the child. This
> is now the only way to invoke a colorFilter child. Internally, we
> support passing a color when invoking a child shader, but I'm not
> exposing that. It's not clearly part of the semantics of the Skia
> pipeline, and is almost never useful. It also exposes users to
> several inconsistencies (skbug.com/11942).
> 3) Because of #2, it's possible that we can't compute a reusable program
> to filter individual colors. In that case, we don't set the constant
> output for constant input optimization, and filterColor4f falls back
> to the slower base-class implementation.
>
> Bug: skia:11813 skia:11942
> Change-Id: I06c41e1b35056e486f3163a72acf6b9535d7fed4
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401917
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
Bug: skia:11813 skia:11942
Change-Id: I2c31b147ed86fa8c4dddefb7066bc1d07fe0d285
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404637
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-04-21 13:57:19 +00:00
|
|
|
fOwner->fChildren[fChild->index] = std::forward<C>(val);
|
2021-03-23 21:04:41 +00:00
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
2020-04-15 18:18:13 +00:00
|
|
|
|
Reland "Better first-class shader & color filter support in runtime effects"
This is a reland of adadb95a9f1ef21ccc5264c7d0bdc83b56cf91e9
... adds a temporary workaround for some Android framework code.
Original change's description:
> Better first-class shader & color filter support in runtime effects
>
> This does a few things, because they're all intertwined:
>
> 1) SkRuntimeEffect's API now includes details about children (which Skia
> stage was declared, not just the name). The factories verify that the
> declared types in the SkSL match up with the C++ types being passed.
> Today, we still only support adding children of the same type, so the
> checks are simple. Once we allow mixing types, we'll be testing the
> declared type against the actual C++ type supplied for each slot.
> 2) Adds sample variants that supply the input color to the child. This
> is now the only way to invoke a colorFilter child. Internally, we
> support passing a color when invoking a child shader, but I'm not
> exposing that. It's not clearly part of the semantics of the Skia
> pipeline, and is almost never useful. It also exposes users to
> several inconsistencies (skbug.com/11942).
> 3) Because of #2, it's possible that we can't compute a reusable program
> to filter individual colors. In that case, we don't set the constant
> output for constant input optimization, and filterColor4f falls back
> to the slower base-class implementation.
>
> Bug: skia:11813 skia:11942
> Change-Id: I06c41e1b35056e486f3163a72acf6b9535d7fed4
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401917
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
Bug: skia:11813 skia:11942
Change-Id: I2c31b147ed86fa8c4dddefb7066bc1d07fe0d285
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404637
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-04-21 13:57:19 +00:00
|
|
|
SkRuntimeEffectBuilder* fOwner;
|
|
|
|
const SkRuntimeEffect::Child* fChild; // nullptr if the child was not found
|
|
|
|
|
|
|
|
// DEPRECATED - Left temporarily for Android
|
|
|
|
int fIndex; // -1 if the child was not found
|
2020-04-15 18:18:13 +00:00
|
|
|
};
|
|
|
|
|
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) }; }
|
Reland "Better first-class shader & color filter support in runtime effects"
This is a reland of adadb95a9f1ef21ccc5264c7d0bdc83b56cf91e9
... adds a temporary workaround for some Android framework code.
Original change's description:
> Better first-class shader & color filter support in runtime effects
>
> This does a few things, because they're all intertwined:
>
> 1) SkRuntimeEffect's API now includes details about children (which Skia
> stage was declared, not just the name). The factories verify that the
> declared types in the SkSL match up with the C++ types being passed.
> Today, we still only support adding children of the same type, so the
> checks are simple. Once we allow mixing types, we'll be testing the
> declared type against the actual C++ type supplied for each slot.
> 2) Adds sample variants that supply the input color to the child. This
> is now the only way to invoke a colorFilter child. Internally, we
> support passing a color when invoking a child shader, but I'm not
> exposing that. It's not clearly part of the semantics of the Skia
> pipeline, and is almost never useful. It also exposes users to
> several inconsistencies (skbug.com/11942).
> 3) Because of #2, it's possible that we can't compute a reusable program
> to filter individual colors. In that case, we don't set the constant
> output for constant input optimization, and filterColor4f falls back
> to the slower base-class implementation.
>
> Bug: skia:11813 skia:11942
> Change-Id: I06c41e1b35056e486f3163a72acf6b9535d7fed4
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/401917
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
Bug: skia:11813 skia:11942
Change-Id: I2c31b147ed86fa8c4dddefb7066bc1d07fe0d285
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404637
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-04-21 13:57:19 +00:00
|
|
|
BuilderChild child(const char* name) {
|
|
|
|
const SkRuntimeEffect::Child* child = fEffect->findChild(name);
|
|
|
|
return { this, child, child ? child->index : -1 };
|
|
|
|
}
|
2020-04-15 18:18:13 +00:00
|
|
|
|
2021-03-23 21:04:41 +00:00
|
|
|
protected:
|
|
|
|
SkRuntimeEffectBuilder() = delete;
|
|
|
|
explicit SkRuntimeEffectBuilder(sk_sp<SkRuntimeEffect> effect)
|
|
|
|
: fEffect(std::move(effect))
|
|
|
|
, fUniforms(SkData::MakeUninitialized(fEffect->uniformSize()))
|
|
|
|
, fChildren(fEffect->children().count()) {}
|
|
|
|
|
|
|
|
SkRuntimeEffectBuilder(SkRuntimeEffectBuilder&&) = default;
|
|
|
|
SkRuntimeEffectBuilder(const SkRuntimeEffectBuilder&) = default;
|
|
|
|
|
|
|
|
SkRuntimeEffectBuilder& operator=(SkRuntimeEffectBuilder&&) = delete;
|
|
|
|
SkRuntimeEffectBuilder& operator=(const SkRuntimeEffectBuilder&) = delete;
|
|
|
|
|
|
|
|
sk_sp<SkData> uniforms() { return fUniforms; }
|
|
|
|
Child* children() { return fChildren.data(); }
|
|
|
|
size_t numChildren() { return fChildren.size(); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
void* writableUniformData() {
|
|
|
|
if (!fUniforms->unique()) {
|
|
|
|
fUniforms = SkData::MakeWithCopy(fUniforms->data(), fUniforms->size());
|
|
|
|
}
|
|
|
|
return fUniforms->writable_data();
|
|
|
|
}
|
|
|
|
|
|
|
|
sk_sp<SkRuntimeEffect> fEffect;
|
|
|
|
sk_sp<SkData> fUniforms;
|
|
|
|
std::vector<Child> fChildren;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
* provides named access to the 'uniform' variables in that block, as well as named access
|
|
|
|
* to a list of child shader slots. Usage:
|
|
|
|
*
|
|
|
|
* sk_sp<SkRuntimeEffect> effect = ...;
|
|
|
|
* SkRuntimeShaderBuilder builder(effect);
|
|
|
|
* builder.uniform("some_uniform_float") = 3.14f;
|
|
|
|
* builder.uniform("some_uniform_matrix") = SkM44::Rotate(...);
|
|
|
|
* builder.child("some_child_effect") = mySkImage->makeShader(...);
|
|
|
|
* ...
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
class SK_API SkRuntimeShaderBuilder : public SkRuntimeEffectBuilder<sk_sp<SkShader>> {
|
|
|
|
public:
|
|
|
|
explicit SkRuntimeShaderBuilder(sk_sp<SkRuntimeEffect>);
|
|
|
|
// This is currently required by Android Framework but may go away if that dependency
|
|
|
|
// can be removed.
|
|
|
|
SkRuntimeShaderBuilder(const SkRuntimeShaderBuilder&) = default;
|
|
|
|
~SkRuntimeShaderBuilder();
|
|
|
|
|
2020-04-15 18:18:13 +00:00
|
|
|
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:
|
2021-03-23 21:04:41 +00:00
|
|
|
using INHERITED = SkRuntimeEffectBuilder<sk_sp<SkShader>>;
|
2020-04-15 18:18:13 +00:00
|
|
|
};
|
|
|
|
|
2019-12-16 14:17:25 +00:00
|
|
|
#endif
|