Add ShaderType::kSolidColor and make Combinations work w/ PaintParams
This is split out of Michael's CL: https://skia-review.googlesource.com/c/skia/+/468459 Bug: skia:12466 Change-Id: Ic38ee577553cf2c0d4da8130e80a11422fa2b92e Reviewed-on: https://skia-review.googlesource.com/c/skia/+/472177 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
24e7ec7713
commit
80ee93d2f5
@ -2129,7 +2129,7 @@ namespace {
|
||||
void precompile(skgpu::Context* context) {
|
||||
using ShaderType = skgpu::ShaderCombo::ShaderType;
|
||||
|
||||
skgpu::PaintCombo c1 { { skgpu::ShaderCombo({ ShaderType::kNone },
|
||||
skgpu::PaintCombo c1 { { skgpu::ShaderCombo({ ShaderType::kSolidColor },
|
||||
{ SkTileMode::kRepeat }) },
|
||||
{ SkBlendMode::kSrcOver, SkBlendMode::kSrc } };
|
||||
context->preCompile(c1);
|
||||
|
@ -26,7 +26,8 @@ namespace mtl { struct BackendContext; }
|
||||
|
||||
struct ShaderCombo {
|
||||
enum class ShaderType {
|
||||
kNone,
|
||||
kNone, // does not modify color buffer, e.g. depth and/or stencil only
|
||||
kSolidColor,
|
||||
kLinearGradient,
|
||||
kRadialGradient,
|
||||
kSweepGradient,
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "experimental/graphite/src/ContextUtils.h"
|
||||
|
||||
#include <string>
|
||||
#include "experimental/graphite/src/DrawList.h" // TODO: split PaintParams out into their own header
|
||||
#include "experimental/graphite/src/DrawTypes.h"
|
||||
#include "experimental/graphite/src/Uniform.h"
|
||||
#include "experimental/graphite/src/UniformCache.h"
|
||||
@ -178,11 +179,12 @@ sk_sp<UniformData> UniformData::Make(int count,
|
||||
return sk_sp<UniformData>(new UniformData(count, uniforms, offsets, data, dataSize));
|
||||
}
|
||||
|
||||
std::tuple<Combination, sk_sp<UniformData>> ExtractCombo(UniformCache* cache, const SkPaint& p) {
|
||||
std::tuple<Combination, sk_sp<UniformData>> ExtractCombo(UniformCache* cache,
|
||||
const PaintParams& p) {
|
||||
Combination result;
|
||||
sk_sp<UniformData> uniforms;
|
||||
|
||||
if (auto s = p.getShader()) {
|
||||
if (auto s = p.shader()) {
|
||||
SkColor colors[kMaxStops];
|
||||
SkColor4f color4fs[kMaxStops];
|
||||
float offsets[kMaxStops];
|
||||
@ -250,21 +252,21 @@ std::tuple<Combination, sk_sp<UniformData>> ExtractCombo(UniformCache* cache, co
|
||||
case SkShader::GradientType::kColor_GradientType:
|
||||
case SkShader::GradientType::kNone_GradientType:
|
||||
default:
|
||||
result.fShaderType = ShaderCombo::ShaderType::kNone;
|
||||
result.fTileMode = SkTileMode::kRepeat;
|
||||
result.fShaderType = ShaderCombo::ShaderType::kSolidColor;
|
||||
result.fTileMode = SkTileMode::kClamp;
|
||||
|
||||
uniforms = make_solid_uniform_data(p.getColor4f());
|
||||
uniforms = make_solid_uniform_data(p.color());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Solid colored paint
|
||||
result.fShaderType = ShaderCombo::ShaderType::kNone;
|
||||
result.fTileMode = SkTileMode::kRepeat;
|
||||
result.fShaderType = ShaderCombo::ShaderType::kSolidColor;
|
||||
result.fTileMode = SkTileMode::kClamp;
|
||||
|
||||
uniforms = make_solid_uniform_data(p.getColor4f());
|
||||
uniforms = make_solid_uniform_data(p.color());
|
||||
}
|
||||
|
||||
result.fBlendMode = p.getBlendMode_or(SkBlendMode::kSrcOver);
|
||||
result.fBlendMode = p.blendMode();
|
||||
|
||||
sk_sp<UniformData> trueUD = cache->findOrCreate(std::move(uniforms));
|
||||
return { result, std::move(trueUD) };
|
||||
@ -320,6 +322,8 @@ std::string GetMSLUniformStruct(ShaderCombo::ShaderType shaderType) {
|
||||
case ShaderCombo::ShaderType::kConicalGradient:
|
||||
return emit_MSL_uniform_struct(kGradientUniforms, kNumGradientUniforms);
|
||||
case ShaderCombo::ShaderType::kNone:
|
||||
return "";
|
||||
case ShaderCombo::ShaderType::kSolidColor:
|
||||
default:
|
||||
return emit_MSL_uniform_struct(kSolidUniforms, kNumSolidUniforms);
|
||||
}
|
||||
|
@ -13,15 +13,14 @@
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTileMode.h"
|
||||
|
||||
class SkPaint;
|
||||
|
||||
namespace skgpu {
|
||||
|
||||
class PaintParams;
|
||||
class Uniform;
|
||||
class UniformCache;
|
||||
|
||||
// A single, fully specified combination resulting from a PaintCombo (i.e., it corresponds to a
|
||||
// specific SkPaint)
|
||||
// specific skgpu::PaintParams object (a subset of SkPaint))
|
||||
struct Combination {
|
||||
bool operator==(const Combination& other) const {
|
||||
return fShaderType == other.fShaderType &&
|
||||
@ -29,8 +28,16 @@ struct Combination {
|
||||
fBlendMode == other.fBlendMode;
|
||||
}
|
||||
|
||||
uint32_t key() const {
|
||||
return (static_cast<int>(fShaderType) << 9) | // 6 values -> 3 bits
|
||||
(static_cast<int>(fTileMode) << 7) | // 4 values -> 2 bits
|
||||
(static_cast<int>(fBlendMode) << 2); // 29 values -> 5 bits
|
||||
}
|
||||
|
||||
ShaderCombo::ShaderType fShaderType = ShaderCombo::ShaderType::kNone;
|
||||
SkTileMode fTileMode = SkTileMode::kRepeat;
|
||||
// Tile mode and blend mode are ignored if shader type is kNone; tile mode is ignored if
|
||||
// shader type is kSolidColor.
|
||||
SkTileMode fTileMode = SkTileMode::kClamp;
|
||||
SkBlendMode fBlendMode = SkBlendMode::kSrc;
|
||||
};
|
||||
|
||||
@ -86,7 +93,7 @@ private:
|
||||
const size_t fDataSize;
|
||||
};
|
||||
|
||||
std::tuple<Combination, sk_sp<UniformData>> ExtractCombo(UniformCache*, const SkPaint&);
|
||||
std::tuple<Combination, sk_sp<UniformData>> ExtractCombo(UniformCache*, const PaintParams&);
|
||||
std::string GetMSLUniformStruct(ShaderCombo::ShaderType);
|
||||
|
||||
} // namespace skgpu
|
||||
|
@ -278,14 +278,10 @@ void Device::drawShape(const Shape& shape,
|
||||
// A draw's order always depends on the clips that must be drawn before it
|
||||
order.dependsOnPaintersOrder(clipOrder);
|
||||
|
||||
auto blendMode = paint.asBlendMode();
|
||||
PaintParams shading{paint.getColor4f(),
|
||||
blendMode.has_value() ? *blendMode : SkBlendMode::kSrcOver,
|
||||
paint.refShader()};
|
||||
|
||||
// If a draw is not opaque, it must be drawn after the most recent draw it intersects with in
|
||||
// order to blend correctly. We always query the most recent draw (even when opaque) because it
|
||||
// also lets Device easily track whether or not there are any overlapping draws.
|
||||
PaintParams shading{paint};
|
||||
const bool opaque = is_opaque(shading);
|
||||
CompressedPaintersOrder prevDraw =
|
||||
fColorDepthBoundsManager->getMostRecentDraw(clip.drawBounds());
|
||||
|
@ -18,21 +18,16 @@ PaintParams::PaintParams(const SkColor4f& color,
|
||||
sk_sp<SkShader> shader)
|
||||
: fColor(color)
|
||||
, fBlendMode(blendMode)
|
||||
, fShader(std::move(shader)) {
|
||||
}
|
||||
PaintParams::PaintParams(const PaintParams& other)
|
||||
: fColor(other.fColor)
|
||||
, fBlendMode(other.fBlendMode)
|
||||
, fShader(other.fShader) {
|
||||
}
|
||||
PaintParams::~PaintParams() {}
|
||||
, fShader(std::move(shader)) {}
|
||||
|
||||
PaintParams& PaintParams::operator=(const PaintParams& other) {
|
||||
fColor = other.fColor;
|
||||
fBlendMode = other.fBlendMode;
|
||||
fShader = other.fShader;
|
||||
return *this;
|
||||
}
|
||||
PaintParams::PaintParams(const SkPaint& paint)
|
||||
: fColor(paint.getColor4f())
|
||||
, fBlendMode(paint.getBlendMode_or(SkBlendMode::kSrcOver))
|
||||
, fShader(paint.refShader()) {}
|
||||
|
||||
PaintParams::PaintParams(const PaintParams& other) = default;
|
||||
PaintParams::~PaintParams() = default;
|
||||
PaintParams& PaintParams::operator=(const PaintParams& other) = default;
|
||||
|
||||
sk_sp<SkShader> PaintParams::refShader() const { return fShader; }
|
||||
|
||||
|
@ -38,6 +38,8 @@ struct VertexWriter;
|
||||
class PaintParams {
|
||||
public:
|
||||
PaintParams(const SkColor4f& color, SkBlendMode, sk_sp<SkShader>);
|
||||
explicit PaintParams(const SkPaint& paint);
|
||||
|
||||
PaintParams(const PaintParams&);
|
||||
~PaintParams();
|
||||
|
||||
|
@ -31,15 +31,8 @@ namespace {
|
||||
// Retrieve the program ID and uniformData ID
|
||||
std::tuple<uint32_t, uint32_t> get_ids_from_paint(skgpu::Recorder* recorder,
|
||||
skgpu::PaintParams params) {
|
||||
// TODO: add an ExtractCombo that takes PaintParams directly?
|
||||
SkPaint p;
|
||||
|
||||
p.setColor(params.color());
|
||||
p.setBlendMode(params.blendMode());
|
||||
p.setShader(params.refShader());
|
||||
|
||||
// TODO: perhaps just return the ids here rather than the sk_sps?
|
||||
auto [ combo, uniformData] = ExtractCombo(recorder->uniformCache(), p);
|
||||
auto [ combo, uniformData] = ExtractCombo(recorder->uniformCache(), params);
|
||||
auto programInfo = recorder->programCache()->findOrCreateProgram(combo);
|
||||
|
||||
return { programInfo->id(), uniformData->id() };
|
||||
|
@ -46,10 +46,18 @@ std::string ProgramCache::ProgramInfo::getMSL() const {
|
||||
"return result;\n"
|
||||
"}\n");
|
||||
break;
|
||||
case ShaderCombo::ShaderType::kNone:
|
||||
// TODO: kNone is for depth-only draws, so should actually have a fragment output type
|
||||
// that only defines a [[depth]] attribute but no color calculation.
|
||||
msl +=
|
||||
"fragment float4 fragmentMain(VertexOutput interpolated [[stage_in]]) {\n"
|
||||
" return float4(0.0, 0.0, 1.0, 1.0);\n"
|
||||
"}\n";
|
||||
break;
|
||||
case ShaderCombo::ShaderType::kRadialGradient:
|
||||
case ShaderCombo::ShaderType::kSweepGradient:
|
||||
case ShaderCombo::ShaderType::kConicalGradient:
|
||||
case ShaderCombo::ShaderType::kNone:
|
||||
case ShaderCombo::ShaderType::kSolidColor:
|
||||
default:
|
||||
msl += std::string(
|
||||
"fragment float4 fragmentShader(VertexOut interpolated [[stage_in]],\n"
|
||||
|
@ -23,7 +23,9 @@ DEF_GRAPHITE_TEST_FOR_CONTEXTS(ProgramCacheTest, reporter, context) {
|
||||
// Add an initial unique program
|
||||
sk_sp<ProgramCache::ProgramInfo> pi1;
|
||||
{
|
||||
Combination c1 { ShaderCombo::ShaderType::kNone, SkTileMode::kRepeat, SkBlendMode::kSrc };
|
||||
Combination c1 { ShaderCombo::ShaderType::kSolidColor,
|
||||
SkTileMode::kRepeat,
|
||||
SkBlendMode::kSrc };
|
||||
pi1 = cache->findOrCreateProgram(c1);
|
||||
REPORTER_ASSERT(reporter, pi1->id() != ProgramCache::kInvalidProgramID);
|
||||
REPORTER_ASSERT(reporter, pi1->combo() == c1);
|
||||
@ -35,7 +37,9 @@ DEF_GRAPHITE_TEST_FOR_CONTEXTS(ProgramCacheTest, reporter, context) {
|
||||
|
||||
// Try to add a duplicate program
|
||||
{
|
||||
Combination c2 { ShaderCombo::ShaderType::kNone, SkTileMode::kRepeat, SkBlendMode::kSrc };
|
||||
Combination c2 { ShaderCombo::ShaderType::kSolidColor,
|
||||
SkTileMode::kRepeat,
|
||||
SkBlendMode::kSrc };
|
||||
sk_sp<ProgramCache::ProgramInfo> pi2 = cache->findOrCreateProgram(c2);
|
||||
REPORTER_ASSERT(reporter, pi2->id() != ProgramCache::kInvalidProgramID);
|
||||
REPORTER_ASSERT(reporter, pi2->id() == pi1->id());
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "tests/Test.h"
|
||||
|
||||
#include "experimental/graphite/src/ContextUtils.h"
|
||||
#include "experimental/graphite/src/DrawList.h" // TODO: split PaintParams out into their own header
|
||||
#include "experimental/graphite/src/UniformCache.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
#include "include/effects/SkGradientShader.h"
|
||||
@ -24,6 +25,9 @@ std::tuple<SkPaint, int> create_paint(skgpu::Combination combo) {
|
||||
int numUniforms = 0;
|
||||
switch (combo.fShaderType) {
|
||||
case skgpu::ShaderCombo::ShaderType::kNone:
|
||||
SkDEBUGFAIL("kNone cannot be represented as an SkPaint");
|
||||
break;
|
||||
case skgpu::ShaderCombo::ShaderType::kSolidColor:
|
||||
numUniforms += 1;
|
||||
break;
|
||||
case skgpu::ShaderCombo::ShaderType::kLinearGradient:
|
||||
@ -60,7 +64,9 @@ DEF_GRAPHITE_TEST(UniformTest, reporter) {
|
||||
|
||||
UniformCache cache;
|
||||
|
||||
for (auto s : { ShaderCombo::ShaderType::kNone,
|
||||
// Intentionally does not include ShaderType::kNone, which represents no fragment shading stage
|
||||
// and is thus not relevant to uniform extraction/caching.
|
||||
for (auto s : { ShaderCombo::ShaderType::kSolidColor,
|
||||
ShaderCombo::ShaderType::kLinearGradient,
|
||||
ShaderCombo::ShaderType::kRadialGradient,
|
||||
ShaderCombo::ShaderType::kSweepGradient,
|
||||
@ -69,8 +75,8 @@ DEF_GRAPHITE_TEST(UniformTest, reporter) {
|
||||
SkTileMode::kRepeat,
|
||||
SkTileMode::kMirror,
|
||||
SkTileMode::kDecal }) {
|
||||
if (s == ShaderCombo::ShaderType::kNone) {
|
||||
tm = SkTileMode::kRepeat; // the TileMode doesn't matter for this case
|
||||
if (s == ShaderCombo::ShaderType::kSolidColor) {
|
||||
tm = SkTileMode::kClamp; // the TileMode doesn't matter for this case
|
||||
}
|
||||
|
||||
for (auto bm : { SkBlendMode::kSrc, SkBlendMode::kSrcOver }) {
|
||||
@ -81,7 +87,7 @@ DEF_GRAPHITE_TEST(UniformTest, reporter) {
|
||||
expected.fBlendMode = bm;
|
||||
|
||||
auto [ p, expectedNumUniforms ] = create_paint(expected);
|
||||
auto [ actual, ud] = ExtractCombo(&cache, p);
|
||||
auto [ actual, ud] = ExtractCombo(&cache, PaintParams(p));
|
||||
REPORTER_ASSERT(reporter, expected == actual);
|
||||
REPORTER_ASSERT(reporter, expectedNumUniforms == ud->count());
|
||||
for (int i = 0; i < ud->count(); ++i) {
|
||||
|
Loading…
Reference in New Issue
Block a user