2019-12-18 16:23:12 +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 "tools/viewer/SkSLSlide.h"
|
|
|
|
|
2020-04-06 17:57:30 +00:00
|
|
|
#include "include/core/SkCanvas.h"
|
2020-12-11 17:51:06 +00:00
|
|
|
#include "include/core/SkFont.h"
|
2019-12-18 20:44:27 +00:00
|
|
|
#include "include/effects/SkGradientShader.h"
|
2020-01-27 21:21:34 +00:00
|
|
|
#include "include/effects/SkPerlinNoiseShader.h"
|
2021-12-08 15:34:52 +00:00
|
|
|
#include "include/sksl/SkSLDebugTrace.h"
|
2019-12-18 20:44:27 +00:00
|
|
|
#include "src/core/SkEnumerate.h"
|
2019-12-18 16:23:12 +00:00
|
|
|
#include "tools/Resources.h"
|
2022-01-07 14:39:55 +00:00
|
|
|
#include "tools/viewer/Viewer.h"
|
2019-12-18 16:23:12 +00:00
|
|
|
|
2019-12-30 20:02:30 +00:00
|
|
|
#include <algorithm>
|
2020-12-11 16:21:35 +00:00
|
|
|
#include <cstdio>
|
2019-12-18 16:23:12 +00:00
|
|
|
#include "imgui.h"
|
|
|
|
|
|
|
|
using namespace sk_app;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2022-01-07 14:39:55 +00:00
|
|
|
static int InputTextCallback(ImGuiInputTextCallbackData* data) {
|
|
|
|
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) {
|
|
|
|
SkString* s = (SkString*)data->UserData;
|
|
|
|
SkASSERT(data->Buf == s->writable_str());
|
|
|
|
SkString tmp(data->Buf, data->BufTextLen);
|
|
|
|
s->swap(tmp);
|
|
|
|
data->Buf = s->writable_str();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-12-18 16:23:12 +00:00
|
|
|
SkSLSlide::SkSLSlide() {
|
|
|
|
// Register types for serialization
|
|
|
|
fName = "SkSL";
|
|
|
|
|
2022-01-07 14:39:55 +00:00
|
|
|
fSkSL =
|
|
|
|
|
2020-11-04 20:40:50 +00:00
|
|
|
"uniform shader child;\n"
|
2019-12-18 16:23:12 +00:00
|
|
|
"\n"
|
2020-08-13 20:59:48 +00:00
|
|
|
"half4 main(float2 p) {\n"
|
2021-09-02 13:26:27 +00:00
|
|
|
" return child.eval(p);\n"
|
2022-01-07 14:39:55 +00:00
|
|
|
"}\n";
|
2020-03-06 20:23:54 +00:00
|
|
|
|
|
|
|
fCodeIsDirty = true;
|
2019-12-18 20:44:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SkSLSlide::load(SkScalar winWidth, SkScalar winHeight) {
|
|
|
|
SkPoint points[] = { { 0, 0 }, { 256, 0 } };
|
|
|
|
SkColor colors[] = { SK_ColorRED, SK_ColorGREEN };
|
|
|
|
|
|
|
|
sk_sp<SkShader> shader;
|
|
|
|
|
2020-07-10 18:08:56 +00:00
|
|
|
fShaders.push_back(std::make_pair("Null", nullptr));
|
|
|
|
|
2019-12-18 20:44:27 +00:00
|
|
|
shader = SkGradientShader::MakeLinear(points, colors, nullptr, 2, SkTileMode::kClamp);
|
|
|
|
fShaders.push_back(std::make_pair("Linear Gradient", shader));
|
|
|
|
|
2020-12-11 16:22:57 +00:00
|
|
|
shader = SkGradientShader::MakeRadial({ 256, 256 }, 256, colors, nullptr, 2,
|
2019-12-18 20:44:27 +00:00
|
|
|
SkTileMode::kClamp);
|
|
|
|
fShaders.push_back(std::make_pair("Radial Gradient", shader));
|
|
|
|
|
2020-12-11 16:22:57 +00:00
|
|
|
shader = SkGradientShader::MakeSweep(256, 256, colors, nullptr, 2);
|
2019-12-18 20:44:27 +00:00
|
|
|
fShaders.push_back(std::make_pair("Sweep Gradient", shader));
|
|
|
|
|
2020-12-10 19:55:43 +00:00
|
|
|
shader = GetResourceAsImage("images/mandrill_256.png")->makeShader(SkSamplingOptions());
|
2019-12-18 20:44:27 +00:00
|
|
|
fShaders.push_back(std::make_pair("Mandrill", shader));
|
2019-12-18 16:23:12 +00:00
|
|
|
|
2020-12-11 19:31:54 +00:00
|
|
|
fResolution = { winWidth, winHeight, 1.0f };
|
2019-12-18 16:23:12 +00:00
|
|
|
}
|
|
|
|
|
2019-12-18 20:44:27 +00:00
|
|
|
void SkSLSlide::unload() {
|
|
|
|
fEffect.reset();
|
|
|
|
fInputs.reset();
|
|
|
|
fChildren.reset();
|
|
|
|
fShaders.reset();
|
|
|
|
}
|
|
|
|
|
2020-06-18 18:18:27 +00:00
|
|
|
bool SkSLSlide::rebuild() {
|
2022-01-07 14:39:55 +00:00
|
|
|
// Some of the standard shadertoy inputs:
|
|
|
|
SkString sksl;
|
|
|
|
if (fShadertoyUniforms) {
|
|
|
|
sksl = "uniform float3 iResolution;\n"
|
|
|
|
"uniform float iTime;\n"
|
|
|
|
"uniform float4 iMouse;\n";
|
|
|
|
}
|
|
|
|
sksl.append(fSkSL);
|
2020-12-11 16:21:35 +00:00
|
|
|
|
|
|
|
// It shouldn't happen, but it's possible to assert in the compiler, especially mid-edit.
|
|
|
|
// To guard against losing your work, write out the shader to a backup file, then remove it
|
|
|
|
// when we compile successfully.
|
|
|
|
constexpr char kBackupFile[] = "sksl.bak";
|
|
|
|
FILE* backup = fopen(kBackupFile, "w");
|
|
|
|
if (backup) {
|
2022-01-07 14:39:55 +00:00
|
|
|
fwrite(fSkSL.c_str(), 1, fSkSL.size(), backup);
|
2020-12-11 16:21:35 +00:00
|
|
|
fclose(backup);
|
|
|
|
}
|
2022-01-07 14:39:55 +00:00
|
|
|
auto [effect, errorText] = SkRuntimeEffect::MakeForShader(sksl);
|
2020-12-11 16:21:35 +00:00
|
|
|
if (backup) {
|
|
|
|
std::remove(kBackupFile);
|
|
|
|
}
|
|
|
|
|
2019-12-19 20:44:56 +00:00
|
|
|
if (!effect) {
|
2022-01-07 14:39:55 +00:00
|
|
|
Viewer::ShaderErrorHandler()->compileError(sksl.c_str(), errorText.c_str());
|
2019-12-18 16:23:12 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
size_t oldSize = fEffect ? fEffect->uniformSize() : 0;
|
|
|
|
fInputs.realloc(effect->uniformSize());
|
|
|
|
if (effect->uniformSize() > oldSize) {
|
|
|
|
memset(fInputs.get() + oldSize, 0, effect->uniformSize() - oldSize);
|
2019-12-18 16:23:12 +00:00
|
|
|
}
|
2021-11-10 19:29:10 +00:00
|
|
|
fChildren.resize_back(effect->children().size());
|
2019-12-18 20:44:27 +00:00
|
|
|
|
2019-12-18 16:23:12 +00:00
|
|
|
fEffect = effect;
|
2020-03-06 20:23:54 +00:00
|
|
|
fCodeIsDirty = false;
|
2019-12-18 16:23:12 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkSLSlide::draw(SkCanvas* canvas) {
|
|
|
|
canvas->clear(SK_ColorWHITE);
|
|
|
|
|
2022-01-07 14:39:55 +00:00
|
|
|
ImGui::Begin("SkSL", nullptr, ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
2019-12-18 16:23:12 +00:00
|
|
|
|
|
|
|
// Edit box for shader code
|
2022-01-07 14:39:55 +00:00
|
|
|
ImGuiInputTextFlags flags = ImGuiInputTextFlags_CallbackResize;
|
|
|
|
ImVec2 boxSize(-1.0f, ImGui::GetTextLineHeight() * 30);
|
|
|
|
if (ImGui::InputTextMultiline("Code", fSkSL.writable_str(), fSkSL.size() + 1, boxSize, flags,
|
|
|
|
InputTextCallback, &fSkSL)) {
|
|
|
|
fCodeIsDirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui::Checkbox("ShaderToy Uniforms (iResolution/iTime/iMouse)", &fShadertoyUniforms)) {
|
2021-12-28 14:30:18 +00:00
|
|
|
fCodeIsDirty = true;
|
|
|
|
}
|
|
|
|
|
2020-03-06 20:23:54 +00:00
|
|
|
if (fCodeIsDirty || !fEffect) {
|
2020-06-18 18:18:27 +00:00
|
|
|
this->rebuild();
|
2019-12-18 16:23:12 +00:00
|
|
|
}
|
|
|
|
|
2019-12-18 20:44:27 +00:00
|
|
|
if (!fEffect) {
|
|
|
|
ImGui::End();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-08 15:34:52 +00:00
|
|
|
bool writeTrace = false;
|
|
|
|
bool writeDump = false;
|
|
|
|
if (!canvas->recordingContext()) {
|
|
|
|
ImGui::InputInt2("Trace Coordinate (X/Y)", fTraceCoord);
|
|
|
|
writeTrace = ImGui::Button("Write Debug Trace (JSON)");
|
|
|
|
writeDump = ImGui::Button("Write Debug Dump (Human-Readable)");
|
|
|
|
}
|
|
|
|
|
2020-12-11 19:31:54 +00:00
|
|
|
// Update fMousePos
|
|
|
|
ImVec2 mousePos = ImGui::GetMousePos();
|
|
|
|
if (ImGui::IsMouseDown(0)) {
|
|
|
|
fMousePos.x = mousePos.x;
|
|
|
|
fMousePos.y = mousePos.y;
|
|
|
|
}
|
|
|
|
if (ImGui::IsMouseClicked(0)) {
|
|
|
|
fMousePos.z = mousePos.x;
|
|
|
|
fMousePos.w = mousePos.y;
|
|
|
|
}
|
|
|
|
fMousePos.z = abs(fMousePos.z) * (ImGui::IsMouseDown(0) ? 1 : -1);
|
|
|
|
fMousePos.w = abs(fMousePos.w) * (ImGui::IsMouseClicked(0) ? 1 : -1);
|
|
|
|
|
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
|
|
|
for (const auto& v : fEffect->uniforms()) {
|
2021-02-03 19:48:41 +00:00
|
|
|
char* data = fInputs.get() + v.offset;
|
2022-01-07 14:39:55 +00:00
|
|
|
if (v.name.equals("iResolution")) {
|
2020-12-11 19:31:54 +00:00
|
|
|
memcpy(data, &fResolution, sizeof(fResolution));
|
|
|
|
continue;
|
|
|
|
}
|
2022-01-07 14:39:55 +00:00
|
|
|
if (v.name.equals("iTime")) {
|
2020-12-11 19:31:54 +00:00
|
|
|
memcpy(data, &fSeconds, sizeof(fSeconds));
|
|
|
|
continue;
|
|
|
|
}
|
2022-01-07 14:39:55 +00:00
|
|
|
if (v.name.equals("iMouse")) {
|
2020-12-11 19:31:54 +00:00
|
|
|
memcpy(data, &fMousePos, sizeof(fMousePos));
|
2020-12-11 15:09:03 +00:00
|
|
|
continue;
|
|
|
|
}
|
2021-02-03 19:48:41 +00:00
|
|
|
switch (v.type) {
|
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
|
|
|
case SkRuntimeEffect::Uniform::Type::kFloat:
|
|
|
|
case SkRuntimeEffect::Uniform::Type::kFloat2:
|
|
|
|
case SkRuntimeEffect::Uniform::Type::kFloat3:
|
|
|
|
case SkRuntimeEffect::Uniform::Type::kFloat4: {
|
2021-02-03 19:48:41 +00:00
|
|
|
int rows = ((int)v.type - (int)SkRuntimeEffect::Uniform::Type::kFloat) + 1;
|
2020-12-11 19:31:54 +00:00
|
|
|
float* f = reinterpret_cast<float*>(data);
|
2021-02-03 19:48:41 +00:00
|
|
|
for (int c = 0; c < v.count; ++c, f += rows) {
|
|
|
|
SkString name = v.isArray() ? SkStringPrintf("%s[%d]", v.name.c_str(), c)
|
|
|
|
: v.name;
|
2019-12-18 16:23:12 +00:00
|
|
|
ImGui::PushID(c);
|
|
|
|
ImGui::DragScalarN(name.c_str(), ImGuiDataType_Float, f, rows, 1.0f);
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
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
|
|
|
case SkRuntimeEffect::Uniform::Type::kFloat2x2:
|
|
|
|
case SkRuntimeEffect::Uniform::Type::kFloat3x3:
|
|
|
|
case SkRuntimeEffect::Uniform::Type::kFloat4x4: {
|
2021-02-03 19:48:41 +00:00
|
|
|
int rows = ((int)v.type - (int)SkRuntimeEffect::Uniform::Type::kFloat2x2) + 2;
|
2019-12-18 16:23:12 +00:00
|
|
|
int cols = rows;
|
2020-12-11 19:31:54 +00:00
|
|
|
float* f = reinterpret_cast<float*>(data);
|
2021-02-03 19:48:41 +00:00
|
|
|
for (int e = 0; e < v.count; ++e) {
|
2019-12-18 16:23:12 +00:00
|
|
|
for (int c = 0; c < cols; ++c, f += rows) {
|
|
|
|
SkString name = v.isArray()
|
2021-02-03 19:48:41 +00:00
|
|
|
? SkStringPrintf("%s[%d][%d]", v.name.c_str(), e, c)
|
|
|
|
: SkStringPrintf("%s[%d]", v.name.c_str(), c);
|
2019-12-18 16:23:12 +00:00
|
|
|
ImGui::DragScalarN(name.c_str(), ImGuiDataType_Float, f, rows, 1.0f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2021-04-01 13:56:07 +00:00
|
|
|
case SkRuntimeEffect::Uniform::Type::kInt:
|
|
|
|
case SkRuntimeEffect::Uniform::Type::kInt2:
|
|
|
|
case SkRuntimeEffect::Uniform::Type::kInt3:
|
|
|
|
case SkRuntimeEffect::Uniform::Type::kInt4: {
|
|
|
|
int rows = ((int)v.type - (int)SkRuntimeEffect::Uniform::Type::kInt) + 1;
|
|
|
|
int* i = reinterpret_cast<int*>(data);
|
|
|
|
for (int c = 0; c < v.count; ++c, i += rows) {
|
|
|
|
SkString name = v.isArray() ? SkStringPrintf("%s[%d]", v.name.c_str(), c)
|
|
|
|
: v.name;
|
|
|
|
ImGui::PushID(c);
|
|
|
|
ImGui::DragScalarN(name.c_str(), ImGuiDataType_S32, i, rows, 1.0f);
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2019-12-18 16:23:12 +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
|
|
|
for (const auto& c : fEffect->children()) {
|
|
|
|
auto curShader =
|
|
|
|
std::find_if(fShaders.begin(), fShaders.end(), [tgt = fChildren[c.index]](auto p) {
|
|
|
|
return p.second == tgt;
|
|
|
|
});
|
|
|
|
SkASSERT(curShader != fShaders.end());
|
|
|
|
|
|
|
|
if (ImGui::BeginCombo(c.name.c_str(), curShader->first)) {
|
2019-12-18 20:44:27 +00:00
|
|
|
for (const auto& namedShader : fShaders) {
|
|
|
|
if (ImGui::Selectable(namedShader.first, curShader->second == namedShader.second)) {
|
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
|
|
|
fChildren[c.index] = namedShader.second;
|
2019-12-18 20:44:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-10 18:08:56 +00:00
|
|
|
static SkColor4f gPaintColor { 1.0f, 1.0f, 1.0f , 1.0f };
|
|
|
|
ImGui::ColorEdit4("Paint Color", gPaintColor.vec());
|
|
|
|
|
2020-12-11 17:51:06 +00:00
|
|
|
ImGui::RadioButton("Fill", &fGeometry, kFill); ImGui::SameLine();
|
|
|
|
ImGui::RadioButton("Circle", &fGeometry, kCircle); ImGui::SameLine();
|
|
|
|
ImGui::RadioButton("RoundRect", &fGeometry, kRoundRect); ImGui::SameLine();
|
|
|
|
ImGui::RadioButton("Capsule", &fGeometry, kCapsule); ImGui::SameLine();
|
|
|
|
ImGui::RadioButton("Text", &fGeometry, kText);
|
|
|
|
|
2019-12-18 16:23:12 +00:00
|
|
|
ImGui::End();
|
|
|
|
|
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
|
|
|
auto inputs = SkData::MakeWithoutCopy(fInputs.get(), fEffect->uniformSize());
|
2021-12-08 15:34:52 +00:00
|
|
|
|
2021-12-10 19:28:05 +00:00
|
|
|
canvas->save();
|
|
|
|
|
2021-12-08 15:34:52 +00:00
|
|
|
sk_sp<SkSL::DebugTrace> debugTrace;
|
2022-02-09 16:56:45 +00:00
|
|
|
auto shader = fEffect->makeShader(std::move(inputs), fChildren.data(), fChildren.count());
|
2021-12-08 15:34:52 +00:00
|
|
|
if (writeTrace || writeDump) {
|
|
|
|
SkIPoint traceCoord = {fTraceCoord[0], fTraceCoord[1]};
|
|
|
|
SkRuntimeEffect::TracedShader traced = SkRuntimeEffect::MakeTraced(std::move(shader),
|
|
|
|
traceCoord);
|
|
|
|
shader = std::move(traced.shader);
|
|
|
|
debugTrace = std::move(traced.debugTrace);
|
2021-12-10 19:28:05 +00:00
|
|
|
|
|
|
|
// Reduce debug trace delay by clipping to a 4x4 rectangle for this paint, centered on the
|
|
|
|
// pixel to trace. A minor complication is that the canvas might have a transform applied to
|
|
|
|
// it, but we want to clip in device space. This can be worked around by resetting the
|
|
|
|
// canvas matrix temporarily.
|
|
|
|
SkM44 canvasMatrix = canvas->getLocalToDevice();
|
|
|
|
canvas->resetMatrix();
|
|
|
|
auto r = SkRect::MakeXYWH(fTraceCoord[0] - 1, fTraceCoord[1] - 1, 4, 4);
|
|
|
|
canvas->clipRect(r, SkClipOp::kIntersect);
|
|
|
|
canvas->setMatrix(canvasMatrix);
|
2021-12-08 15:34:52 +00:00
|
|
|
}
|
2019-12-18 16:23:12 +00:00
|
|
|
SkPaint p;
|
2020-07-10 18:08:56 +00:00
|
|
|
p.setColor4f(gPaintColor);
|
2019-12-18 16:23:12 +00:00
|
|
|
p.setShader(std::move(shader));
|
2020-12-11 17:51:06 +00:00
|
|
|
|
|
|
|
switch (fGeometry) {
|
|
|
|
case kFill:
|
|
|
|
canvas->drawPaint(p);
|
|
|
|
break;
|
|
|
|
case kCircle:
|
|
|
|
canvas->drawCircle({ 256, 256 }, 256, p);
|
|
|
|
break;
|
|
|
|
case kRoundRect:
|
|
|
|
canvas->drawRoundRect({ 0, 0, 512, 512 }, 64, 64, p);
|
|
|
|
break;
|
|
|
|
case kCapsule:
|
|
|
|
canvas->drawRoundRect({ 0, 224, 512, 288 }, 32, 32, p);
|
|
|
|
break;
|
|
|
|
case kText: {
|
|
|
|
SkFont font;
|
|
|
|
font.setSize(SkIntToScalar(96));
|
|
|
|
canvas->drawSimpleText("Hello World", strlen("Hello World"), SkTextEncoding::kUTF8, 0,
|
|
|
|
256, font, p);
|
|
|
|
} break;
|
|
|
|
default: break;
|
|
|
|
}
|
2021-12-08 15:34:52 +00:00
|
|
|
|
2021-12-10 19:28:05 +00:00
|
|
|
canvas->restore();
|
|
|
|
|
2021-12-08 15:34:52 +00:00
|
|
|
if (debugTrace && writeTrace) {
|
|
|
|
SkFILEWStream traceFile("SkVMDebugTrace.json");
|
|
|
|
debugTrace->writeTrace(&traceFile);
|
|
|
|
}
|
|
|
|
if (debugTrace && writeDump) {
|
|
|
|
SkFILEWStream dumpFile("SkVMDebugTrace.dump.txt");
|
|
|
|
debugTrace->dump(&dumpFile);
|
|
|
|
}
|
2019-12-18 16:23:12 +00:00
|
|
|
}
|
2020-12-11 15:09:03 +00:00
|
|
|
|
|
|
|
bool SkSLSlide::animate(double nanos) {
|
|
|
|
fSeconds = static_cast<float>(nanos * 1E-9);
|
|
|
|
return true;
|
|
|
|
}
|