2021-04-16 18:54:43 +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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "include/core/SkBitmap.h"
|
|
|
|
#include "include/core/SkCanvas.h"
|
|
|
|
#include "include/core/SkColorFilter.h"
|
|
|
|
#include "include/core/SkData.h"
|
|
|
|
#include "include/core/SkPaint.h"
|
|
|
|
#include "include/core/SkSurface.h"
|
|
|
|
#include "include/effects/SkRuntimeEffect.h"
|
|
|
|
#include "include/gpu/GrDirectContext.h"
|
|
|
|
#include "include/sksl/DSLRuntimeEffects.h"
|
2021-07-20 17:16:57 +00:00
|
|
|
#include "src/core/SkRuntimeEffectPriv.h"
|
2021-04-16 18:54:43 +00:00
|
|
|
#include "src/core/SkTLazy.h"
|
|
|
|
#include "src/gpu/GrColor.h"
|
|
|
|
#include "src/sksl/SkSLCompiler.h"
|
|
|
|
#include "tests/Test.h"
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
using namespace SkSL::dsl;
|
|
|
|
|
|
|
|
class DSLTestEffect {
|
|
|
|
public:
|
|
|
|
DSLTestEffect(skiatest::Reporter* r, sk_sp<SkSurface> surface)
|
|
|
|
: fReporter(r)
|
|
|
|
, fCaps(SkSL::ShaderCapsFactory::Standalone())
|
|
|
|
, fCompiler(std::make_unique<SkSL::Compiler>(fCaps.get()))
|
|
|
|
, fSurface(std::move(surface)) {}
|
|
|
|
|
|
|
|
void start() {
|
|
|
|
StartRuntimeShader(fCompiler.get());
|
|
|
|
}
|
|
|
|
|
2021-06-15 13:17:05 +00:00
|
|
|
void end(bool expectSuccess = true) {
|
2021-07-20 17:16:57 +00:00
|
|
|
SkRuntimeEffect::Options options;
|
|
|
|
SkRuntimeEffectPriv::EnableFragCoord(&options);
|
|
|
|
sk_sp<SkRuntimeEffect> effect = EndRuntimeShader(options);
|
2021-06-15 13:17:05 +00:00
|
|
|
REPORTER_ASSERT(fReporter, effect ? expectSuccess : !expectSuccess);
|
|
|
|
if (effect) {
|
|
|
|
fBuilder.init(std::move(effect));
|
|
|
|
}
|
2021-04-16 18:54:43 +00:00
|
|
|
}
|
|
|
|
|
2021-06-23 17:51:55 +00:00
|
|
|
SkRuntimeShaderBuilder::BuilderUniform uniform(skstd::string_view name) {
|
|
|
|
return fBuilder->uniform(SkString(name).c_str());
|
2021-04-16 18:54:43 +00:00
|
|
|
}
|
2021-06-23 17:51:55 +00:00
|
|
|
|
|
|
|
SkRuntimeShaderBuilder::BuilderChild child(skstd::string_view name) {
|
|
|
|
return fBuilder->child(SkString(name).c_str());
|
2021-04-16 18:54:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
using PreTestFn = std::function<void(SkCanvas*, SkPaint*)>;
|
|
|
|
|
|
|
|
void test(GrColor TL, GrColor TR, GrColor BL, GrColor BR,
|
|
|
|
PreTestFn preTestCallback = nullptr) {
|
|
|
|
auto shader = fBuilder->makeShader(nullptr, false);
|
|
|
|
if (!shader) {
|
|
|
|
REPORT_FAILURE(fReporter, "shader", SkString("Effect didn't produce a shader"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SkCanvas* canvas = fSurface->getCanvas();
|
|
|
|
SkPaint paint;
|
|
|
|
paint.setShader(std::move(shader));
|
|
|
|
paint.setBlendMode(SkBlendMode::kSrc);
|
|
|
|
|
|
|
|
canvas->save();
|
|
|
|
if (preTestCallback) {
|
|
|
|
preTestCallback(canvas, &paint);
|
|
|
|
}
|
|
|
|
canvas->drawPaint(paint);
|
|
|
|
canvas->restore();
|
|
|
|
|
|
|
|
GrColor actual[4];
|
|
|
|
SkImageInfo info = fSurface->imageInfo();
|
|
|
|
if (!fSurface->readPixels(info, actual, info.minRowBytes(), 0, 0)) {
|
|
|
|
REPORT_FAILURE(fReporter, "readPixels", SkString("readPixels failed"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
GrColor expected[4] = {TL, TR, BL, BR};
|
|
|
|
if (0 != memcmp(actual, expected, sizeof(actual))) {
|
|
|
|
REPORT_FAILURE(fReporter, "Runtime effect didn't match expectations",
|
|
|
|
SkStringPrintf("\n"
|
|
|
|
"Expected: [ %08x %08x %08x %08x ]\n"
|
|
|
|
"Got : [ %08x %08x %08x %08x ]\n"
|
|
|
|
"SkSL:\n%s\n",
|
|
|
|
TL, TR, BL, BR, actual[0], actual[1], actual[2],
|
|
|
|
actual[3], fBuilder->effect()->source().c_str()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void test(GrColor expected, PreTestFn preTestCallback = nullptr) {
|
|
|
|
this->test(expected, expected, expected, expected, preTestCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2021-11-19 15:59:59 +00:00
|
|
|
skiatest::Reporter* fReporter;
|
|
|
|
std::unique_ptr<SkSL::ShaderCaps> fCaps;
|
|
|
|
std::unique_ptr<SkSL::Compiler> fCompiler;
|
|
|
|
sk_sp<SkSurface> fSurface;
|
|
|
|
SkTLazy<SkRuntimeShaderBuilder> fBuilder;
|
2021-04-16 18:54:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrRecordingContext* rContext) {
|
|
|
|
SkImageInfo info = SkImageInfo::Make(2, 2, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
|
|
|
sk_sp<SkSurface> surface = rContext
|
|
|
|
? SkSurface::MakeRenderTarget(rContext, SkBudgeted::kNo, info)
|
|
|
|
: SkSurface::MakeRaster(info);
|
|
|
|
REPORTER_ASSERT(r, surface);
|
|
|
|
using float4 = std::array<float, 4>;
|
|
|
|
using int4 = std::array<int, 4>;
|
|
|
|
DSLTestEffect effect(r, surface);
|
|
|
|
|
|
|
|
// Local coords
|
|
|
|
{
|
|
|
|
effect.start();
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
Parameter p(kFloat2_Type, "p");
|
2021-04-16 18:54:43 +00:00
|
|
|
Function(kHalf4_Type, "main", p).define(
|
|
|
|
Return(Half4(Half2(p - 0.5), 0, 1))
|
|
|
|
);
|
|
|
|
effect.end();
|
|
|
|
effect.test(0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use of a simple uniform. (Draw twice with two values to ensure it's updated).
|
|
|
|
{
|
|
|
|
effect.start();
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
GlobalVar gColor(kUniform_Modifier, kFloat4_Type);
|
|
|
|
Declare(gColor);
|
|
|
|
Parameter p(kFloat2_Type, "p");
|
2021-05-04 18:30:02 +00:00
|
|
|
Function(kHalf4_Type, "main", p).define(
|
2021-04-16 18:54:43 +00:00
|
|
|
Return(Half4(gColor))
|
|
|
|
);
|
|
|
|
effect.end();
|
2021-07-20 19:23:04 +00:00
|
|
|
effect.uniform(SkString(gColor.name()).c_str()) = float4{ 0.0f, 0.25f, 0.75f, 1.0f };
|
2021-04-16 18:54:43 +00:00
|
|
|
effect.test(0xFFBF4000);
|
2021-07-20 19:23:04 +00:00
|
|
|
effect.uniform(SkString(gColor.name()).c_str()) = float4{ 1.0f, 0.0f, 0.0f, 0.498f };
|
2021-09-24 14:51:47 +00:00
|
|
|
effect.test(0x7F0000FF); // Tests that we don't clamp to valid premul
|
2021-04-16 18:54:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Same, with integer uniforms
|
|
|
|
{
|
|
|
|
effect.start();
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
GlobalVar gColor(kUniform_Modifier, kInt4_Type);
|
|
|
|
Declare(gColor);
|
|
|
|
Parameter p(kFloat2_Type, "p");
|
2021-05-04 18:30:02 +00:00
|
|
|
Function(kHalf4_Type, "main", p).define(
|
2021-04-16 18:54:43 +00:00
|
|
|
Return(Half4(gColor) / 255)
|
|
|
|
);
|
|
|
|
effect.end();
|
2021-07-20 19:23:04 +00:00
|
|
|
effect.uniform(SkString(gColor.name()).c_str()) = int4{ 0x00, 0x40, 0xBF, 0xFF };
|
2021-04-16 18:54:43 +00:00
|
|
|
effect.test(0xFFBF4000);
|
2021-07-20 19:23:04 +00:00
|
|
|
effect.uniform(SkString(gColor.name()).c_str()) = int4{ 0xFF, 0x00, 0x00, 0x7F };
|
2021-09-24 14:51:47 +00:00
|
|
|
effect.test(0x7F0000FF); // Tests that we don't clamp to valid premul
|
2021-04-16 18:54:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Test sk_FragCoord (device coords). Rotate the canvas to be sure we're seeing device coords.
|
|
|
|
// Since the surface is 2x2, we should see (0,0), (1,0), (0,1), (1,1). Multiply by 0.498 to
|
|
|
|
// make sure we're not saturating unexpectedly.
|
|
|
|
{
|
|
|
|
effect.start();
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
Parameter p(kFloat2_Type, "p");
|
2021-05-04 18:30:02 +00:00
|
|
|
Function(kHalf4_Type, "main", p).define(
|
2021-04-16 18:54:43 +00:00
|
|
|
Return(Half4(0.498 * (Half2(Swizzle(sk_FragCoord(), X, Y)) - 0.5), 0, 1))
|
|
|
|
);
|
|
|
|
effect.end();
|
|
|
|
effect.test(0xFF000000, 0xFF00007F, 0xFF007F00, 0xFF007F7F,
|
|
|
|
[](SkCanvas* canvas, SkPaint*) { canvas->rotate(45.0f); });
|
|
|
|
}
|
|
|
|
|
|
|
|
// Runtime effects should use relaxed precision rules by default
|
|
|
|
{
|
|
|
|
effect.start();
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
Parameter p(kFloat2_Type, "p");
|
2021-04-16 18:54:43 +00:00
|
|
|
Function(kHalf4_Type, "main", p).define(
|
|
|
|
Return(Float4(p - 0.5, 0, 1))
|
|
|
|
);
|
|
|
|
effect.end();
|
|
|
|
effect.test(0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ... and support *returning* float4, not just half4
|
|
|
|
{
|
|
|
|
effect.start();
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
Parameter p(kFloat2_Type, "p");
|
2021-04-16 18:54:43 +00:00
|
|
|
Function(kFloat4_Type, "main", p).define(
|
|
|
|
Return(Float4(p - 0.5, 0, 1))
|
|
|
|
);
|
|
|
|
effect.end();
|
|
|
|
effect.test(0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF);
|
|
|
|
}
|
|
|
|
|
2021-06-15 13:17:05 +00:00
|
|
|
// Test error reporting. We put this before a couple of successful tests to ensure that a
|
|
|
|
// failure doesn't leave us in a broken state.
|
|
|
|
{
|
2021-08-13 21:29:51 +00:00
|
|
|
class SimpleErrorReporter : public SkSL::ErrorReporter {
|
2021-06-15 13:17:05 +00:00
|
|
|
public:
|
2021-09-07 17:49:07 +00:00
|
|
|
void handleError(skstd::string_view msg, SkSL::PositionInfo pos) override {
|
2021-08-13 21:29:51 +00:00
|
|
|
fMsg += msg;
|
2021-06-15 13:17:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SkSL::String fMsg;
|
2021-08-13 21:29:51 +00:00
|
|
|
} errorReporter;
|
2022-01-12 14:56:36 +00:00
|
|
|
|
|
|
|
// Test errors that occur while constructing DSL nodes
|
2021-06-15 13:17:05 +00:00
|
|
|
effect.start();
|
2021-08-13 21:29:51 +00:00
|
|
|
SetErrorReporter(&errorReporter);
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
Parameter p(kFloat2_Type, "p");
|
2021-06-15 13:17:05 +00:00
|
|
|
Function(kHalf4_Type, "main", p).define(
|
|
|
|
Return(1) // Error, type mismatch
|
|
|
|
);
|
|
|
|
effect.end(false);
|
2021-08-13 21:29:51 +00:00
|
|
|
REPORTER_ASSERT(r, errorReporter.fMsg == "expected 'half4', but found 'int'");
|
2022-01-12 14:56:36 +00:00
|
|
|
errorReporter.fMsg = "";
|
|
|
|
errorReporter.resetErrorCount();
|
|
|
|
|
|
|
|
// Test errors that occur while finalizing the runtime effect
|
|
|
|
effect.start();
|
|
|
|
SetErrorReporter(&errorReporter);
|
|
|
|
effect.end(false);
|
|
|
|
REPORTER_ASSERT(r, errorReporter.fMsg == "missing 'main' function");
|
2021-06-15 13:17:05 +00:00
|
|
|
}
|
|
|
|
|
2021-04-16 18:54:43 +00:00
|
|
|
// Mutating coords should work. (skbug.com/10918)
|
|
|
|
{
|
|
|
|
effect.start();
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
Parameter p(kFloat2_Type, "p");
|
2021-04-16 18:54:43 +00:00
|
|
|
Function(kFloat4_Type, "main", p).define(
|
|
|
|
p -= 0.5,
|
|
|
|
Return(Float4(p, 0, 1))
|
|
|
|
);
|
|
|
|
effect.end();
|
|
|
|
effect.test(0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
effect.start();
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
Parameter p1(kInOut_Modifier, kFloat2_Type, "p");
|
2021-04-16 18:54:43 +00:00
|
|
|
Function moveCoords(kVoid_Type, "moveCoords", p1);
|
|
|
|
moveCoords.define(
|
|
|
|
p1 -= 0.5
|
|
|
|
);
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
Parameter p2(kFloat2_Type, "p");
|
2021-04-16 18:54:43 +00:00
|
|
|
Function(kFloat4_Type, "main", p2).define(
|
|
|
|
moveCoords(p2),
|
|
|
|
Return(Float4(p2, 0, 1))
|
|
|
|
);
|
|
|
|
effect.end();
|
|
|
|
effect.test(0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Sampling children
|
|
|
|
//
|
|
|
|
|
|
|
|
// Sampling a null child should return the paint color
|
|
|
|
{
|
|
|
|
effect.start();
|
Broke DSLVar into separate subclasses
Previously, DSLVar represented local, global, and parameter variables.
This splits it into three separate subclasses.
In addition to just being a cleaner API in general, this also addresses
an issue we ran into with the upcoming DSLParser: previously, a global
DSLVar's storage was not set correctly until DeclareGlobal was called,
so an AddToSymbolTable call prior to DeclareGlobal would create the
SkSL variable with the wrong storage, causing spurious errors on
global-only modifiers. But holding off on the AddToSymbolTable tends to
break constructs like "int x = 0, y = x", so improving the API seemed
like the best way to address it.
Now that we have greater type safety around variables, we can
potentially avoid having to call AddToSymbolTable for DSLVar and
DSLGlobalVar altogether, since we know they are both supposed to end up
in the symbol table, but that isn't something I want to change in this
CL.
Change-Id: I5f390a7384ce0af6a2131d84f97fc5e5b318063f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/428576
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2021-07-15 14:35:54 +00:00
|
|
|
GlobalVar child(kUniform_Modifier, kShader_Type, "child");
|
|
|
|
Declare(child);
|
|
|
|
Parameter p2(kFloat2_Type, "p");
|
2021-04-28 21:41:57 +00:00
|
|
|
Function(kFloat4_Type, "main", p2).define(
|
2021-09-09 18:31:31 +00:00
|
|
|
Return(child.eval(p2))
|
2021-04-16 18:54:43 +00:00
|
|
|
);
|
|
|
|
effect.end();
|
2021-06-23 17:51:55 +00:00
|
|
|
effect.child(child.name()) = nullptr;
|
2021-04-16 18:54:43 +00:00
|
|
|
effect.test(0xFF00FFFF,
|
|
|
|
[](SkCanvas*, SkPaint* paint) { paint->setColor4f({1.0f, 1.0f, 0.0f, 1.0f}); });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DEF_TEST(DSLRuntimeEffectSimple, r) {
|
|
|
|
test_RuntimeEffect_Shaders(r, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DSLRuntimeEffectSimple_GPU, r, ctxInfo) {
|
|
|
|
test_RuntimeEffect_Shaders(r, ctxInfo.directContext());
|
|
|
|
}
|