blob: 58aeadd5dcfcbac2708abb794029b20f56ffc54e [file] [log] [blame]
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkKeyHelpers_DEFINED
#define SkKeyHelpers_DEFINED
#ifdef SK_GRAPHITE_ENABLED
#include "include/gpu/graphite/Context.h"
#include "src/gpu/graphite/TextureProxy.h"
#endif
#include "include/core/SkBlendMode.h"
#include "include/core/SkM44.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkShader.h"
#include "include/core/SkSpan.h"
#include "include/core/SkTileMode.h"
#include "include/private/SkColorData.h"
class SkData;
class SkPaintParamsKeyBuilder;
class SkPipelineDataGatherer;
class SkRuntimeEffect;
class SkUniquePaintParamsID;
class SkKeyContext;
#ifdef SK_ENABLE_PRECOMPILE
namespace skgpu::graphite {
enum class ShaderType : uint32_t;
}
#endif
// The KeyHelpers can be used to manually construct an SkPaintParamsKey
struct PassthroughShaderBlock {
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*);
};
struct PassthroughBlenderBlock {
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*);
};
struct SolidColorShaderBlock {
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const SkPMColor4f&);
};
struct GradientShaderBlocks {
struct GradientData {
// TODO: For the sprint we only support 8 stops in the gradients
static constexpr int kMaxStops = 8;
// This ctor is used during pre-compilation when we don't have enough information to
// extract uniform data. However, we must be able to provide enough data to make all the
// relevant decisions about which code snippets to use.
GradientData(SkShader::GradientType, int numStops);
// This ctor is used when extracting information from PaintParams. It must provide
// enough data to generate the uniform data the selected code snippet will require.
GradientData(SkShader::GradientType,
const SkM44& localMatrix,
SkPoint point0, SkPoint point1,
float radius0, float radius1,
float bias, float scale,
SkTileMode,
int numStops,
SkColor4f* colors,
float* offsets);
bool operator==(const GradientData& rhs) const {
return fType == rhs.fType &&
fLocalMatrix == rhs.fLocalMatrix &&
fPoints[0] == rhs.fPoints[0] &&
fPoints[1] == rhs.fPoints[1] &&
fRadii[0] == rhs.fRadii[0] &&
fRadii[1] == rhs.fRadii[1] &&
fBias == rhs.fBias &&
fScale == rhs.fScale &&
fTM == rhs.fTM &&
fNumStops == rhs.fNumStops &&
!memcmp(fColor4fs, rhs.fColor4fs, sizeof(fColor4fs)) &&
!memcmp(fOffsets, rhs.fOffsets, sizeof(fOffsets));
}
bool operator!=(const GradientData& rhs) const { return !(*this == rhs); }
// Layout options.
SkShader::GradientType fType;
SkM44 fLocalMatrix;
SkPoint fPoints[2];
float fRadii[2];
// Layout options for sweep gradient.
float fBias;
float fScale;
SkTileMode fTM;
int fNumStops;
SkColor4f fColor4fs[kMaxStops];
float fOffsets[kMaxStops];
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const GradientData&);
};
struct LocalMatrixShaderBlock {
struct LMShaderData {
LMShaderData(const SkMatrix& localMatrix)
: fLocalMatrix(localMatrix) {
}
const SkM44 fLocalMatrix;
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const LMShaderData&);
};
struct ImageShaderBlock {
struct ImageData {
ImageData(const SkSamplingOptions& sampling,
SkTileMode tileModeX,
SkTileMode tileModeY,
SkRect subset,
const SkMatrix& localMatrix);
SkSamplingOptions fSampling;
SkTileMode fTileModes[2];
SkRect fSubset;
const SkMatrix& fLocalMatrix;
#ifdef SK_GRAPHITE_ENABLED
// TODO: Currently this is only filled in when we're generating the key from an actual
// SkImageShader. In the pre-compile case we will need to create a Graphite promise
// image which holds the appropriate data.
sk_sp<skgpu::graphite::TextureProxy> fTextureProxy;
#endif
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const ImageData&);
};
struct PorterDuffBlendShaderBlock {
struct PorterDuffBlendShaderData {
SkSpan<const float> fPorterDuffConstants;
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const PorterDuffBlendShaderData&);
};
struct BlendShaderBlock {
struct BlendShaderData {
SkBlendMode fBM;
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const BlendShaderData&);
};
struct MatrixColorFilterBlock {
struct MatrixColorFilterData {
MatrixColorFilterData(const float matrix[20],
bool inHSLA)
: fMatrix(matrix[ 0], matrix[ 1], matrix[ 2], matrix[ 3],
matrix[ 5], matrix[ 6], matrix[ 7], matrix[ 8],
matrix[10], matrix[11], matrix[12], matrix[13],
matrix[15], matrix[16], matrix[17], matrix[18])
, fTranslate(matrix[4], matrix[9], matrix[14], matrix[19])
, fInHSLA(inHSLA) {
}
SkM44 fMatrix;
skvx::float4 fTranslate;
bool fInHSLA;
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const MatrixColorFilterData&);
};
struct BlendColorFilterBlock {
struct BlendColorFilterData {
BlendColorFilterData(SkBlendMode blendMode, const SkPMColor4f& srcColor)
: fBlendMode(blendMode)
, fSrcColor(srcColor) {
}
SkBlendMode fBlendMode;
SkPMColor4f fSrcColor;
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const BlendColorFilterData&);
};
struct ComposeColorFilterBlock {
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*);
};
struct TableColorFilterBlock {
struct TableColorFilterData {
TableColorFilterData();
#ifdef SK_GRAPHITE_ENABLED
sk_sp<skgpu::graphite::TextureProxy> fTextureProxy;
#endif
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const TableColorFilterData&);
};
struct GaussianColorFilterBlock {
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*);
};
struct BlendModeBlock {
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
SkBlendMode);
};
struct PrimitiveBlendModeBlock {
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
SkBlendMode);
};
struct RuntimeShaderBlock {
struct ShaderData {
// This ctor is used during pre-compilation when we don't have enough information to
// extract uniform data.
ShaderData(sk_sp<const SkRuntimeEffect> effect);
// This ctor is used when extracting information from PaintParams.
ShaderData(sk_sp<const SkRuntimeEffect> effect,
const SkMatrix& localMatrix,
sk_sp<const SkData> uniforms);
bool operator==(const ShaderData& rhs) const;
bool operator!=(const ShaderData& rhs) const { return !(*this == rhs); }
// Runtime shader data.
sk_sp<const SkRuntimeEffect> fEffect;
SkMatrix fLocalMatrix;
sk_sp<const SkData> fUniforms;
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const ShaderData&);
};
struct RuntimeColorFilterBlock {
struct ColorFilterData {
// This ctor is used during pre-compilation when we don't have enough information to
// extract uniform data.
ColorFilterData(sk_sp<const SkRuntimeEffect> effect);
// This ctor is used when extracting information from PaintParams.
ColorFilterData(sk_sp<const SkRuntimeEffect> effect, sk_sp<const SkData> uniforms);
bool operator==(const ColorFilterData& rhs) const;
bool operator!=(const ColorFilterData& rhs) const { return !(*this == rhs); }
// Runtime shader data.
sk_sp<const SkRuntimeEffect> fEffect;
sk_sp<const SkData> fUniforms;
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const ColorFilterData&);
};
struct RuntimeBlenderBlock : public RuntimeColorFilterBlock {
// Runtime Blenders use the same key builder as runtime color filters.
using BlenderData = ColorFilterData;
};
#endif // SkKeyHelpers_DEFINED