2053 {
2055
2056
2057
2060
2063 if (!algorithm) {
2064 return {};
2065 }
2066
2067
2068 LayerSpace<SkISize> radii =
2069 LayerSpace<SkSize>({3.f*sigma.width(), 3.f*sigma.height()}).
ceil();
2070 auto maxOutput = fInputs[0].fImage.layerBounds();
2071 maxOutput.outset(radii);
2072
2073 auto outputBounds = this->outputBounds(maxOutput);
2075 return {};
2076 }
2077
2078
2079
2080
2081 auto sampleBounds = outputBounds;
2082 sampleBounds.
outset(radii);
2083
2086
2087 FilterResult resolved = fInputs[0].fImage.resolve(fContext, sampleBounds);
2088 if (!resolved) {
2089 return {};
2090 }
2091 auto srcRelativeOutput = outputBounds;
2092 srcRelativeOutput.
offset(-resolved.layerBounds().topLeft());
2094 resolved.fImage,
2099 return resolved;
2100 }
2101
2102 float sx = sigma.width() > algorithm->
maxSigma() ? algorithm->
maxSigma()/sigma.width() : 1.f;
2103 float sy = sigma.height() > algorithm->
maxSigma() ? algorithm->
maxSigma()/sigma.height() : 1.f;
2104
2105
2106
2107
2110 LayerSpace<SkSize>({sx, sy}),
2112 if (!lowResImage) {
2113 return {};
2114 }
2117
2118
2119
2120 PixelSpace<SkMatrix> layerToLowRes;
2122 PixelSpace<SkSize> lowResSigma = layerToLowRes.mapSize(sigma);
2123
2124
2125 lowResSigma = PixelSpace<SkSize>{{
std::min(algorithm->
maxSigma(), lowResSigma.width()),
2127 PixelSpace<SkIRect> lowResMaxOutput{
SkISize{lowResImage.fImage->
width(),
2128 lowResImage.fImage->height()}};
2129
2130 PixelSpace<SkIRect> srcRelativeOutput;
2133
2134
2135 srcRelativeOutput = lowResMaxOutput;
2136 } else {
2137
2138
2139 srcRelativeOutput = layerToLowRes.mapRect(outputBounds);
2140
2141
2142
2143 lowResMaxOutput.outset(PixelSpace<SkSize>({3.f * lowResSigma.width(),
2144 3.f * lowResSigma.height()}).
ceil());
2145 srcRelativeOutput = lowResMaxOutput.relevantSubset(srcRelativeOutput,
2146 lowResImage.tileMode());
2147
2148
2149 SkASSERT(!srcRelativeOutput.isEmpty());
2150
2151
2152
2153 srcRelativeOutput.outset(PixelSpace<SkISize>({1, 1}));
2154 }
2155
2159 if (lowResImage.canClampToTransparentBoundary(BoundsAnalysis::kSimple)) {
2160
2162 blurOutputBounds.
offset(1, 1);
2164 }
2165
2166 lowResBlur = algorithm->
blur(
SkSize(lowResSigma),
2167 lowResBlur,
2170 blurOutputBounds);
2171
2175
2177 }
2178
2179 result.fTransform.postConcat(lowResImage.fTransform);
2181
2182
2183
2184
2185
2186 outputBounds = this->outputBounds(
2187 result.fTransform.mapRect(LayerSpace<SkIRect>(
result.fImage->dimensions())));
2188 }
2189 result.fLayerBounds = outputBounds;
2190 result.fTileMode = lowResImage.tileMode();
2192}
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
virtual float maxSigma() const =0
virtual bool supportsOnlyDecalTiling() const =0
virtual sk_sp< SkSpecialImage > blur(SkSize sigma, sk_sp< SkSpecialImage > src, const SkIRect &srcRect, SkTileMode tileMode, const SkIRect &dstRect) const =0
virtual const Algorithm * findAlgorithm(SkSize sigma, SkColorType colorType) const =0
sk_sp< SkSpecialImage > makePixelOutset() const
SkISize dimensions() const
virtual const SkBlurEngine * getBlurEngine() const =0
virtual bool useLegacyFilterResultBlur() const
SkColorType colorType() const
const Backend * backend() const
Context withNewDesiredOutput(const LayerSpace< SkIRect > &desiredOutput) const
SkTileMode tileMode() const
LayerSpace< SkIPoint > topLeft() const
void outset(const LayerSpace< SkISize > &delta)
void offset(const LayerSpace< IVector > &v)
static float min(float r, float g, float b)
SIN Vec< N, float > ceil(const Vec< N, float > &x)
static constexpr SkIRect MakeSize(const SkISize &size)
void offset(int32_t dx, int32_t dy)
constexpr int32_t width() const