Integrate clamp to border into FP optimization flags
Bug: skia:
Change-Id: I89bf20a06942e8d00168c5e8b50b336e99785b9a
Reviewed-on: https://skia-review.googlesource.com/c/177502
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/effects/imagefilters/SkDisplacementMapEffect.cpp b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
index 7dc6804..a29c38c 100644
--- a/src/effects/imagefilters/SkDisplacementMapEffect.cpp
+++ b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
@@ -178,8 +178,6 @@
std::unique_ptr<GrFragmentProcessor> clone() const override;
private:
- static OptimizationFlags OptimizationFlags(GrPixelConfig colorConfig);
-
GrDisplacementMapEffect(const GrDisplacementMapEffect&);
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
@@ -429,13 +427,6 @@
GrGLDisplacementMapEffect::GenKey(*this, caps, b);
}
-GrFragmentProcessor::OptimizationFlags GrDisplacementMapEffect::OptimizationFlags(
- GrPixelConfig colorConfig) {
- return GrPixelConfigIsOpaque(colorConfig)
- ? GrFragmentProcessor::kPreservesOpaqueInput_OptimizationFlag
- : GrFragmentProcessor::kNone_OptimizationFlags;
-}
-
GrDisplacementMapEffect::GrDisplacementMapEffect(
SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
@@ -444,7 +435,8 @@
const SkMatrix& offsetMatrix,
sk_sp<GrTextureProxy> color,
const SkISize& colorDimensions)
- : INHERITED(kGrDisplacementMapEffect_ClassID, OptimizationFlags(color->config()))
+ : INHERITED(kGrDisplacementMapEffect_ClassID,
+ GrFragmentProcessor::kNone_OptimizationFlags)
, fDisplacementTransform(offsetMatrix, displacement.get())
, fDisplacementSampler(displacement)
, fColorTransform(color.get())
@@ -462,8 +454,7 @@
}
GrDisplacementMapEffect::GrDisplacementMapEffect(const GrDisplacementMapEffect& that)
- : INHERITED(kGrDisplacementMapEffect_ClassID,
- OptimizationFlags(that.fColorSampler.proxy()->config()))
+ : INHERITED(kGrDisplacementMapEffect_ClassID, that.optimizationFlags())
, fDisplacementTransform(that.fDisplacementTransform)
, fDisplacementSampler(that.fDisplacementSampler)
, fColorTransform(that.fColorTransform)
diff --git a/src/effects/imagefilters/SkMorphologyImageFilter.cpp b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
index 662343b..6ddc80d 100644
--- a/src/effects/imagefilters/SkMorphologyImageFilter.cpp
+++ b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
@@ -309,13 +309,17 @@
int radius,
Type type,
const float range[2])
- : INHERITED(kGrMorphologyEffect_ClassID, ModulateByConfigOptimizationFlags(proxy->config()))
+ : INHERITED(kGrMorphologyEffect_ClassID,
+ ModulateForClampedSamplerOptFlags(proxy->config()))
, fCoordTransform(proxy.get())
, fTextureSampler(std::move(proxy))
, fDirection(direction)
, fRadius(radius)
, fType(type)
, fUseRange(SkToBool(range)) {
+ // Make sure the sampler's ctor uses the clamp wrap mode
+ SkASSERT(fTextureSampler.samplerState().wrapModeX() == GrSamplerState::WrapMode::kClamp &&
+ fTextureSampler.samplerState().wrapModeY() == GrSamplerState::WrapMode::kClamp);
this->addCoordTransform(&fCoordTransform);
this->setTextureSamplerCnt(1);
if (fUseRange) {
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index 8069541..82a3d18 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -260,8 +260,21 @@
* This assumes that the subclass output color will be a modulation of the input color with a
* value read from a texture of the passed config and that the texture contains premultiplied
* color or alpha values that are in range.
+ *
+ * Since there are multiple ways in which a sampler may have its coordinates clamped or wrapped,
+ * callers must determine on their own if the sampling uses a decal strategy in any way, in
+ * which case the texture may become transparent regardless of the pixel config.
*/
- static OptimizationFlags ModulateByConfigOptimizationFlags(GrPixelConfig config) {
+ static OptimizationFlags ModulateForSamplerOptFlags(GrPixelConfig config, bool samplingDecal) {
+ if (samplingDecal) {
+ return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+ } else {
+ return ModulateForClampedSamplerOptFlags(config);
+ }
+ }
+
+ // As above, but callers should somehow ensure or assert their sampler still uses clamping
+ static OptimizationFlags ModulateForClampedSamplerOptFlags(GrPixelConfig config) {
if (GrPixelConfigIsOpaque(config)) {
return kCompatibleWithCoverageAsAlpha_OptimizationFlag |
kPreservesOpaqueInput_OptimizationFlag;
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index 35ee12e..a320b2e 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -121,7 +121,9 @@
const SkMatrix& matrix,
const GrSamplerState::WrapMode wrapModes[2],
GrTextureDomain::Mode modeX, GrTextureDomain::Mode modeY)
- : INHERITED{kGrBicubicEffect_ClassID, ModulateByConfigOptimizationFlags(proxy->config())}
+ : INHERITED{kGrBicubicEffect_ClassID,
+ ModulateForSamplerOptFlags(proxy->config(),
+ GrTextureDomain::IsDecalSampled(wrapModes, modeX,modeY))}
, fCoordTransform(matrix, proxy.get())
, fDomain(proxy.get(),
GrTextureDomain::MakeTexelDomain(
@@ -136,10 +138,13 @@
GrBicubicEffect::GrBicubicEffect(sk_sp<GrTextureProxy> proxy,
const SkMatrix& matrix,
const SkRect& domain)
- : INHERITED(kGrBicubicEffect_ClassID, ModulateByConfigOptimizationFlags(proxy->config()))
+ : INHERITED(kGrBicubicEffect_ClassID, ModulateForClampedSamplerOptFlags(proxy->config()))
, fCoordTransform(matrix, proxy.get())
, fDomain(proxy.get(), domain, GrTextureDomain::kClamp_Mode, GrTextureDomain::kClamp_Mode)
, fTextureSampler(std::move(proxy)) {
+ // Make sure the sampler's ctor uses the clamp wrap mode
+ SkASSERT(fTextureSampler.samplerState().wrapModeX() == GrSamplerState::WrapMode::kClamp &&
+ fTextureSampler.samplerState().wrapModeY() == GrSamplerState::WrapMode::kClamp);
this->addCoordTransform(&fCoordTransform);
this->setTextureSamplerCnt(1);
}
diff --git a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
index 57006de..9a4c69b 100644
--- a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
+++ b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
@@ -216,12 +216,16 @@
GrTextureDomain::Mode mode,
int bounds[2])
: INHERITED(kGrGaussianConvolutionFragmentProcessor_ClassID,
- ModulateByConfigOptimizationFlags(proxy->config()))
+ ModulateForSamplerOptFlags(proxy->config(),
+ mode == GrTextureDomain::kDecal_Mode))
, fCoordTransform(proxy.get())
, fTextureSampler(std::move(proxy))
, fRadius(radius)
, fDirection(direction)
, fMode(mode) {
+ // Make sure the sampler's ctor uses the clamp wrap mode
+ SkASSERT(fTextureSampler.samplerState().wrapModeX() == GrSamplerState::WrapMode::kClamp &&
+ fTextureSampler.samplerState().wrapModeY() == GrSamplerState::WrapMode::kClamp);
this->addCoordTransform(&fCoordTransform);
this->setTextureSamplerCnt(1);
SkASSERT(radius <= kMaxKernelRadius);
diff --git a/src/gpu/effects/GrSimpleTextureEffect.fp b/src/gpu/effects/GrSimpleTextureEffect.fp
index 18ce3a9..06d36d2 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.fp
+++ b/src/gpu/effects/GrSimpleTextureEffect.fp
@@ -46,9 +46,9 @@
}
@optimizationFlags {
- kCompatibleWithCoverageAsAlpha_OptimizationFlag |
- (GrPixelConfigIsOpaque(image->config()) ? kPreservesOpaqueInput_OptimizationFlag :
- kNone_OptimizationFlags)
+ ModulateForSamplerOptFlags(image->config(),
+ samplerParams.wrapModeX() == GrSamplerState::WrapMode::kClampToBorder ||
+ samplerParams.wrapModeY() == GrSamplerState::WrapMode::kClampToBorder)
}
void main() {
diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h
index fb4e373..5e8730a 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.h
+++ b/src/gpu/effects/GrSimpleTextureEffect.h
@@ -48,10 +48,12 @@
GrSimpleTextureEffect(sk_sp<GrTextureProxy> image, SkMatrix44 matrix,
GrSamplerState samplerParams)
: INHERITED(kGrSimpleTextureEffect_ClassID,
- (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag |
- (GrPixelConfigIsOpaque(image->config())
- ? kPreservesOpaqueInput_OptimizationFlag
- : kNone_OptimizationFlags))
+ (OptimizationFlags)ModulateForSamplerOptFlags(
+ image->config(),
+ samplerParams.wrapModeX() ==
+ GrSamplerState::WrapMode::kClampToBorder ||
+ samplerParams.wrapModeY() ==
+ GrSamplerState::WrapMode::kClampToBorder))
, fImage(std::move(image), samplerParams)
, fMatrix(matrix)
, fImageCoordTransform(matrix, fImage.proxy()) {
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index f452ca7..c710245 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -249,16 +249,6 @@
}
///////////////////////////////////////////////////////////////////////////////
-inline GrFragmentProcessor::OptimizationFlags GrTextureDomainEffect::OptFlags(
- GrPixelConfig config, GrTextureDomain::Mode modeX, GrTextureDomain::Mode modeY) {
- if (modeX == GrTextureDomain::kDecal_Mode || modeY == GrTextureDomain::kDecal_Mode ||
- !GrPixelConfigIsOpaque(config)) {
- return GrFragmentProcessor::kCompatibleWithCoverageAsAlpha_OptimizationFlag;
- } else {
- return GrFragmentProcessor::kCompatibleWithCoverageAsAlpha_OptimizationFlag |
- GrFragmentProcessor::kPreservesOpaqueInput_OptimizationFlag;
- }
-}
std::unique_ptr<GrFragmentProcessor> GrTextureDomainEffect::Make(
sk_sp<GrTextureProxy> proxy,
@@ -291,7 +281,9 @@
GrTextureDomain::Mode modeX,
GrTextureDomain::Mode modeY,
const GrSamplerState& sampler)
- : INHERITED(kGrTextureDomainEffect_ClassID, OptFlags(proxy->config(), modeX, modeY))
+ : INHERITED(kGrTextureDomainEffect_ClassID,
+ ModulateForSamplerOptFlags(proxy->config(),
+ GrTextureDomain::IsDecalSampled(sampler, modeX, modeY)))
, fCoordTransform(matrix, proxy.get())
, fTextureDomain(proxy.get(), domain, modeX, modeY)
, fTextureSampler(std::move(proxy), sampler) {
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index 33f3e17..7ff2721 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -79,6 +79,24 @@
texelRect.fRight - insetX, texelRect.fBottom - insetY);
}
+ // Convenience to determine if any axis of a texture uses an explicit decal mode or the hardware
+ // clamp to border decal mode.
+ static bool IsDecalSampled(GrSamplerState::WrapMode wrapX, GrSamplerState::WrapMode wrapY,
+ Mode modeX, Mode modeY) {
+ return wrapX == GrSamplerState::WrapMode::kClampToBorder ||
+ wrapY == GrSamplerState::WrapMode::kClampToBorder ||
+ modeX == kDecal_Mode ||
+ modeY == kDecal_Mode;
+ }
+
+ static bool IsDecalSampled(const GrSamplerState::WrapMode wraps[2], Mode modeX, Mode modeY) {
+ return IsDecalSampled(wraps[0], wraps[1], modeX, modeY);
+ }
+
+ static bool IsDecalSampled(const GrSamplerState& sampler, Mode modeX, Mode modeY) {
+ return IsDecalSampled(sampler.wrapModeX(), sampler.wrapModeY(), modeX, modeY);
+ }
+
bool operator==(const GrTextureDomain& that) const {
return fModeX == that.fModeX && fModeY == that.fModeY &&
(kIgnore_Mode == fModeX || (fDomain.fLeft == that.fDomain.fLeft &&
@@ -213,9 +231,6 @@
explicit GrTextureDomainEffect(const GrTextureDomainEffect&);
- static OptimizationFlags OptFlags(GrPixelConfig config, GrTextureDomain::Mode modeX,
- GrTextureDomain::Mode modeY);
-
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;