269 lines
14 KiB
C++
269 lines
14 KiB
C++
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef skgpu_graphite_precompile_PrecompileShader_DEFINED
|
|
#define skgpu_graphite_precompile_PrecompileShader_DEFINED
|
|
|
|
#include "include/gpu/graphite/precompile/PrecompileBase.h"
|
|
|
|
#include "include/core/SkBlendMode.h"
|
|
#include "include/core/SkImageInfo.h"
|
|
#include "include/effects/SkGradient.h"
|
|
|
|
class SkColorSpace;
|
|
|
|
namespace skgpu::graphite {
|
|
|
|
class PrecompileBlender;
|
|
class PrecompileColorFilter;
|
|
class PrecompileShaderPriv;
|
|
|
|
/** \class PrecompileShader
|
|
This class corresponds to the SkShader class in the main API.
|
|
*/
|
|
class SK_API PrecompileShader : public PrecompileBase {
|
|
public:
|
|
/**
|
|
* This is the Precompile correlate to SkShader::makeWithLocalMatrix. The actual matrix
|
|
* involved is abstracted away, except for whether or the not the matrix involves perspective
|
|
* so the correct generated shader variation is chosen.
|
|
* The PrecompileShaders::LocalMatrix factory can be used to generate a set of shaders
|
|
* that would've been generated via multiple makeWithLocalMatrix calls. That is, rather than
|
|
* performing:
|
|
* sk_sp<PrecompileShader> option1 = source1->makeWithLocalMatrix(false);
|
|
* sk_sp<PrecompileShader> option2 = source2->makeWithLocalMatrix(false);
|
|
* one could call:
|
|
* sk_sp<PrecompileShader> combinedOptions = LocalMatrix({ source1, source2 }, false);
|
|
*/
|
|
sk_sp<PrecompileShader> makeWithLocalMatrix(bool isPerspective) const;
|
|
|
|
/**
|
|
* This is the Precompile correlate to SkShader::makeWithColorFilter.
|
|
* The PrecompileShaders::ColorFilter factory can be used to generate a set of shaders that
|
|
* would've been generated via multiple makeWithColorFilter calls. That is, rather than
|
|
* performing:
|
|
* sk_sp<PrecompileShader> option1 = source->makeWithColorFilter(colorFilter1);
|
|
* sk_sp<PrecompileShader> option2 = source->makeWithColorFilter(colorFilter2);
|
|
* one could call:
|
|
* sk_sp<PrecompileShader> combinedOptions = ColorFilter({ source },
|
|
* { colorFilter1, colorFilter2 });
|
|
* With an alternative use case one could also use the ColorFilter factory thusly:
|
|
* sk_sp<PrecompileShader> combinedOptions = ColorFilter({ source1, source2 },
|
|
* { colorFilter });
|
|
*/
|
|
sk_sp<PrecompileShader> makeWithColorFilter(sk_sp<PrecompileColorFilter>) const;
|
|
|
|
/**
|
|
* This is the Precompile correlate to SkShader::makeWithWorkingColorSpace.
|
|
* The PrecompileShaders::WorkingColorSpace factory can be used to generate a set of shaders
|
|
* that would've been generated via multiple makeWithWorkingColorSpace calls. That is, rather
|
|
* than performing:
|
|
* sk_sp<PrecompileShader> option1 = source->makeWithWorkingColorSpace(colorSpace1);
|
|
* sk_sp<PrecompileShader> option2 = source->makeWithWorkingColorSpace(colorSpace2);
|
|
* one could call:
|
|
* sk_sp<PrecompileShader> combinedOptions = WorkingColorSpace({ source },
|
|
* { colorSpace1,
|
|
* colorSpace2 });
|
|
* With an alternative use case one could also use the WorkingColorSpace factory thusly:
|
|
* sk_sp<PrecompileShader> combinedOptions = WorkingColorSpace({ source1, source2 },
|
|
* { colorSpace });
|
|
*/
|
|
sk_sp<PrecompileShader> makeWithWorkingColorSpace(sk_sp<SkColorSpace> inputCS,
|
|
sk_sp<SkColorSpace> outputCS=nullptr) const;
|
|
|
|
// Provides access to functions that aren't part of the public API.
|
|
PrecompileShaderPriv priv();
|
|
const PrecompileShaderPriv priv() const; // NOLINT(readability-const-return-type)
|
|
|
|
protected:
|
|
friend class PrecompileShaderPriv;
|
|
|
|
PrecompileShader() : PrecompileBase(Type::kShader) {}
|
|
~PrecompileShader() override;
|
|
|
|
virtual bool isConstant(int /* desiredCombination */) const { return false; }
|
|
virtual bool isOpaque(int /* desiredCombination */) const = 0;
|
|
|
|
virtual bool isALocalMatrixShader() const { return false; }
|
|
};
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// This is the Precompile correlate to the SkShaders namespace in the main API
|
|
namespace PrecompileShaders {
|
|
// --- This block of eight matches the SkShaders factories in SkShader.h
|
|
// Note that some of the details of the main API have been elided since they don't impact
|
|
// the generated shader (e.g., the color parameter to the Color() factories).
|
|
SK_API sk_sp<PrecompileShader> Empty();
|
|
SK_API sk_sp<PrecompileShader> Color();
|
|
SK_API sk_sp<PrecompileShader> Color(sk_sp<SkColorSpace>);
|
|
SK_API sk_sp<PrecompileShader> Blend(SkSpan<const SkBlendMode> blendModes,
|
|
SkSpan<const sk_sp<PrecompileShader>> dsts,
|
|
SkSpan<const sk_sp<PrecompileShader>> srcs);
|
|
SK_API sk_sp<PrecompileShader> Blend(SkSpan<const sk_sp<PrecompileBlender>> blenders,
|
|
SkSpan<const sk_sp<PrecompileShader>> dsts,
|
|
SkSpan<const sk_sp<PrecompileShader>> srcs);
|
|
SK_API sk_sp<PrecompileShader> CoordClamp(SkSpan<const sk_sp<PrecompileShader>>);
|
|
|
|
enum class ImageShaderFlags : uint16_t {
|
|
kNone = 0,
|
|
|
|
kCubicSampling = 1 << 1,
|
|
kIncludeAlphaOnly = 1 << 2,
|
|
|
|
kAll = kCubicSampling | kIncludeAlphaOnly,
|
|
kExcludeCubic = kIncludeAlphaOnly,
|
|
kNoAlphaNoCubic = kNone,
|
|
};
|
|
|
|
static constexpr SkTileMode kAllTileModes[] = {
|
|
SkTileMode::kClamp,
|
|
SkTileMode::kRepeat,
|
|
SkTileMode::kMirror,
|
|
SkTileMode::kDecal,
|
|
};
|
|
|
|
/**
|
|
In the main Skia API ImageShaders are usually created via a SkImage::makeShader call.
|
|
Since the SkImage used to create the ImageShader is unlikely to be present at precompilation
|
|
time this entry point allows the equivalent precompilation program structure to be created.
|
|
Note that this factory is for non-YUV SkImages, the YUVImage factory (below) should be used
|
|
to represent the shading and sampling required for YUV images.
|
|
|
|
@param shaderFlags Specify the sampling variations that will be precompiled.
|
|
@param colorInfos a span of SkColorInfos to narrow down the combinations.
|
|
In general, the color info affects the swizzle and colorSpace
|
|
transformation of the final Pipeline.
|
|
@param tileModes a span of SkTileModes to narrow down the combinations.
|
|
The default will generate all possible combinations. Passing an
|
|
empty SkSpan will eliminate the Shader-based sampling combinations.
|
|
@return A precompile shader capturing the specified combinations
|
|
*/
|
|
SK_API sk_sp<PrecompileShader> Image(ImageShaderFlags = ImageShaderFlags::kAll,
|
|
SkSpan<const SkColorInfo> = {},
|
|
SkSpan<const SkTileMode> = { kAllTileModes });
|
|
|
|
/** DEPRECATED
|
|
* Use above version.
|
|
*/
|
|
SK_API sk_sp<PrecompileShader> Image(SkSpan<const SkColorInfo> colorInfos,
|
|
SkSpan<const SkTileMode> = { kAllTileModes });
|
|
|
|
// As with the above Image call, raw ImageShaders are usually created via an
|
|
// SkImage::makeRawShader call. The RawImage call allows the equivalent precompilation
|
|
// program structure to be created without needing the SkImage.
|
|
SK_API sk_sp<PrecompileShader> RawImage(ImageShaderFlags = ImageShaderFlags::kExcludeCubic,
|
|
SkSpan<const SkColorInfo> = {},
|
|
SkSpan<const SkTileMode> = { kAllTileModes });
|
|
|
|
enum class YUVImageShaderFlags : uint16_t {
|
|
kNone = 0,
|
|
|
|
kHardwareSamplingNoSwizzle = 1 << 1,
|
|
kHardwareSampling = 1 << 2,
|
|
kShaderBasedSampling = 1 << 3,
|
|
kCubicSampling = 1 << 4,
|
|
|
|
kExcludeCubic = kHardwareSamplingNoSwizzle | kHardwareSampling | kShaderBasedSampling,
|
|
kNoCubicNoNonSwizzledHW = kHardwareSamplingNoSwizzle | kShaderBasedSampling,
|
|
};
|
|
|
|
/**
|
|
In the main Skia API, the specifics of the SkImage used for the SkImage::makeShader call
|
|
can determine whether normal or YUV sampling is required. This entry point allows clients
|
|
to specify that the future image will be a YUV image.
|
|
|
|
@param shaderFlags Specify the sampling variations that will be precompiled.
|
|
In practice, YUV images are rarely cubic-sampling.
|
|
@param colorInfos a span of SkColorInfos to narrow down the combinations.
|
|
In general, the color info affects the swizzle and colorSpace
|
|
transformation of the final Pipeline.
|
|
@return A precompile shader capturing the specified combinations
|
|
*/
|
|
SK_API sk_sp<PrecompileShader> YUVImage(
|
|
YUVImageShaderFlags = YUVImageShaderFlags::kExcludeCubic,
|
|
SkSpan<const SkColorInfo> = {});
|
|
|
|
// --- This block of two matches the SkShaders factories in SkPerlinNoiseShader.h
|
|
// Again, most of the details have been elided.
|
|
SK_API sk_sp<PrecompileShader> MakeFractalNoise();
|
|
SK_API sk_sp<PrecompileShader> MakeTurbulence();
|
|
|
|
enum class GradientShaderFlags : uint16_t {
|
|
kNone = 0,
|
|
|
|
kSmall = 1 << 1,
|
|
kMedium = 1 << 2,
|
|
kLarge = 1 << 3,
|
|
|
|
kAll = kSmall | kMedium | kLarge,
|
|
kNoLarge = kSmall | kMedium,
|
|
};
|
|
|
|
// --- This block of four matches all the factories in SkGradientShader (SkGradient.h)
|
|
SK_API sk_sp<PrecompileShader> LinearGradient(
|
|
GradientShaderFlags = GradientShaderFlags::kAll,
|
|
SkGradient::Interpolation = SkGradient::Interpolation());
|
|
SK_API sk_sp<PrecompileShader> RadialGradient(
|
|
GradientShaderFlags = GradientShaderFlags::kAll,
|
|
SkGradient::Interpolation = SkGradient::Interpolation());
|
|
SK_API sk_sp<PrecompileShader> TwoPointConicalGradient(
|
|
GradientShaderFlags = GradientShaderFlags::kAll,
|
|
SkGradient::Interpolation = SkGradient::Interpolation());
|
|
SK_API sk_sp<PrecompileShader> SweepGradient(
|
|
GradientShaderFlags = GradientShaderFlags::kAll,
|
|
SkGradient::Interpolation = SkGradient::Interpolation());
|
|
|
|
// Normally, SkPicture shaders are only created via SkPicture::makeShader. Since the
|
|
// SkPicture to be drawn, most likely, won't be available at precompilation time, this
|
|
// entry point can be used to create a precompilation equivalent.
|
|
// Note: this will precompile the program that draws the SkPicture. It, obviously, won't
|
|
// precompile any SkPaints within the SkPicture.
|
|
SK_API sk_sp<PrecompileShader> Picture();
|
|
|
|
// Normally, LocalMatrixShaders are only created via SkShader::makeWithLocalMatrix.
|
|
// However, in the combination API, clients may want to create a set of precompile
|
|
// LocalMatrixShaders (i.e., pass an SkSpan to the factory function vs just creating a
|
|
// single option). This entry point allows that use case.
|
|
// Note: PrecompileShader::makeWithLocalMatrix() can still be used and works as expected.
|
|
SK_API sk_sp<PrecompileShader> LocalMatrix(SkSpan<const sk_sp<PrecompileShader>> wrapped,
|
|
bool isPerspective = false);
|
|
|
|
// Normally, ColorFilterShaders are only created via SkShader::makeWithColorFilter.
|
|
// However, in the combination API, clients may want to create a set of precompile
|
|
// ColorFilterShaders (i.e., pass SkSpans to the factory function vs just creating a
|
|
// single option). This entry point allows that use case.
|
|
// Note: PrecompileShader::makeWithColorFilter can still be used and works as expected.
|
|
SK_API sk_sp<PrecompileShader> ColorFilter(
|
|
SkSpan<const sk_sp<PrecompileShader>> shaders,
|
|
SkSpan<const sk_sp<PrecompileColorFilter>> colorFilters);
|
|
|
|
// Normally, WorkingColorSpaceShaders are only created via SkShader::makeWithWorkingColorSpace.
|
|
// However, in the combination API, clients may want to create a set of precompile
|
|
// WorkingColorSpaceShaders (i.e., pass SkSpans to the factory function vs just creating a
|
|
// single option). This entry point allows that use case.
|
|
// Note: PrecompileShader::makeWithWorkingColorSpace can still be used and works as expected.
|
|
|
|
// This variant creates the cross product of `inputSpaces` and `outputSpaces`.
|
|
// An empty list is interpreted as matching either the dst color space (for `inputSpaces`) or
|
|
// matching the input space (for `outputSpaces`).
|
|
SK_API sk_sp<PrecompileShader> WorkingColorSpace(
|
|
SkSpan<const sk_sp<PrecompileShader>> shaders,
|
|
SkSpan<const sk_sp<SkColorSpace>> inputSpaces,
|
|
SkSpan<const sk_sp<SkColorSpace>> outputSpaces = {});
|
|
|
|
// This variant takes a span of input and output color spaces pairs explicitly.
|
|
SK_API sk_sp<PrecompileShader> WorkingColorSpaceExplicit(
|
|
SkSpan<const sk_sp<PrecompileShader>> shaders,
|
|
SkSpan<const std::pair</*input =*/sk_sp<SkColorSpace>,
|
|
/*output=*/sk_sp<SkColorSpace>>> inputAndOutputSpaces);
|
|
|
|
} // namespace PrecompileShaders
|
|
|
|
} // namespace skgpu::graphite
|
|
|
|
#endif // skgpu_graphite_precompile_PrecompileShader_DEFINED
|