Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | List of all members
skif::FilterResult::Builder Class Reference

#include <SkImageFilterTypes.h>

Public Member Functions

 Builder (const Context &context)
 
 ~Builder ()
 
Builderadd (const FilterResult &input, std::optional< LayerSpace< SkIRect > > sampleBounds={}, SkEnumBitMask< ShaderFlags > inputFlags=ShaderFlags::kNone, const SkSamplingOptions &inputSampling=kDefaultSampling)
 
FilterResult merge ()
 
FilterResult blur (const LayerSpace< SkSize > &sigma)
 
template<typename ShaderFn >
FilterResult eval (ShaderFn shaderFn, std::optional< LayerSpace< SkIRect > > explicitOutput={}, bool evaluateInParameterSpace=false)
 

Detailed Description

Definition at line 995 of file SkImageFilterTypes.h.

Constructor & Destructor Documentation

◆ Builder()

skif::FilterResult::Builder::Builder ( const Context context)

Definition at line 1763 of file SkImageFilterTypes.cpp.

1763: fContext(context) {}

◆ ~Builder()

skif::FilterResult::Builder::~Builder ( )
default

Member Function Documentation

◆ add()

Builder & skif::FilterResult::Builder::add ( const FilterResult input,
std::optional< LayerSpace< SkIRect > >  sampleBounds = {},
SkEnumBitMask< ShaderFlags inputFlags = ShaderFlags::kNone,
const SkSamplingOptions inputSampling = kDefaultSampling 
)
inline

Definition at line 1012 of file SkImageFilterTypes.h.

1013 {},
1015 const SkSamplingOptions& inputSampling = kDefaultSampling) {
1016 fInputs.push_back({input, sampleBounds, inputFlags, inputSampling});
1017 return *this;
1018 }
static constexpr SkSamplingOptions kDefaultSampling

◆ blur()

FilterResult skif::FilterResult::Builder::blur ( const LayerSpace< SkSize > &  sigma)

Definition at line 1861 of file SkImageFilterTypes.cpp.

1861 {
1862 SkASSERT(fInputs.size() == 1);
1863
1864 // TODO: The blur functor is only supported for GPU contexts; SkBlurImageFilter should have
1865 // detected this.
1866 const SkBlurEngine* blurEngine = fContext.backend()->getBlurEngine();
1867 SkASSERT(blurEngine);
1868
1869 // TODO: All tilemodes are applied right now in resolve() so query with just kDecal
1870 const SkBlurEngine::Algorithm* algorithm = blurEngine->findAlgorithm(
1871 SkSize(sigma), fContext.backend()->colorType());
1872 if (!algorithm) {
1873 return {};
1874 }
1875
1876 // TODO: Move resizing logic out of GrBlurUtils into this function
1877 SkASSERT(sigma.width() <= algorithm->maxSigma() && sigma.height() <= algorithm->maxSigma());
1878
1879 // TODO: De-duplicate this logic between SkBlurImageFilter, here, and skgpu::BlurUtils.
1881 LayerSpace<SkSize>({3.f*sigma.width(), 3.f*sigma.height()}).ceil();
1882 auto maxOutput = fInputs[0].fImage.layerBounds();
1883 maxOutput.outset(radii);
1884
1885 // TODO: If the input image is periodic, the output that's calculated can be the original image
1886 // size and then have the layer bounds and tilemode of the output image apply the tile again.
1887 // Similarly, a clamped blur can be restricted to a radius-outset buffer of the image bounds
1888 // (vs. layer bounds) and rendered with clamp tiling.
1889 const auto outputBounds = this->outputBounds(maxOutput);
1890 if (outputBounds.isEmpty()) {
1891 return {};
1892 }
1893
1894 // These are the source pixels that will be read from the input image, which can be calculated
1895 // internally because the blur's access pattern is well defined (vs. needing it to be provided
1896 // in Builder::add()).
1897 auto sampleBounds = outputBounds;
1898 sampleBounds.outset(radii);
1899
1900 // TODO: If the blur implementation requires downsampling, we should incorporate any deferred
1901 // transform and colorfilter to the first rescale step instead of generating a full resolution
1902 // simple image first.
1903 // TODO: The presence of a non-decal tilemode should not force resolving to a simple image; it
1904 // should be incorporated into the image that's sampled by the blur effect (modulo biasing edge
1905 // pixels somehow for very large clamp blurs).
1906 // TODO: resolve() doesn't actually guarantee that the returned image has the same color space
1907 // as the Context, but probably should since the blur algorithm operates in the color space of
1908 // the input image.
1909 FilterResult resolved = fInputs[0].fImage.resolve(fContext, sampleBounds);
1910 if (!resolved) {
1911 return {};
1912 }
1913
1914 // TODO: Can blur() take advantage of AutoSurface? Right now the GPU functions are responsible
1915 // for creating their own target surfaces.
1916 auto srcRelativeOutput = outputBounds;
1917 srcRelativeOutput.offset(-resolved.layerBounds().topLeft());
1918 resolved = {algorithm->blur(SkSize(sigma),
1919 resolved.fImage,
1920 SkIRect::MakeSize(resolved.fImage->dimensions()),
1922 SkIRect(srcRelativeOutput)),
1923 outputBounds.topLeft()};
1924 // TODO: Allow the blur functor to provide an upscaling transform that is applied to the
1925 // FilterResult so that a render pass can possibly be elided if this is the final operation.
1926 return resolved;
1927}
#define SkASSERT(cond)
Definition SkAssert.h:116
virtual float maxSigma() 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
int size() const
Definition SkTArray.h:416
virtual const SkBlurEngine * getBlurEngine() const =0
SkColorType colorType() const
const Backend * backend() const
LayerSpace< SkIPoint > topLeft() const
void outset(const LayerSpace< SkISize > &delta)
void offset(const LayerSpace< IVector > &v)
SIN Vec< N, float > ceil(const Vec< N, float > &x)
Definition SkVx.h:702
static constexpr SkIRect MakeSize(const SkISize &size)
Definition SkRect.h:66

◆ eval()

template<typename ShaderFn >
FilterResult skif::FilterResult::Builder::eval ( ShaderFn  shaderFn,
std::optional< LayerSpace< SkIRect > >  explicitOutput = {},
bool  evaluateInParameterSpace = false 
)
inline

Definition at line 1049 of file SkImageFilterTypes.h.

1050 {},
1051 bool evaluateInParameterSpace=false) {
1052 auto outputBounds = this->outputBounds(explicitOutput);
1053 if (outputBounds.isEmpty()) {
1054 return {};
1055 }
1056
1057 auto inputShaders = this->createInputShaders(outputBounds, evaluateInParameterSpace);
1058 return this->drawShader(shaderFn(inputShaders), outputBounds, evaluateInParameterSpace);
1059 }

◆ merge()

FilterResult skif::FilterResult::Builder::merge ( )

Definition at line 1832 of file SkImageFilterTypes.cpp.

1832 {
1833 // merge() could return an empty image on 0 added inputs, but this should have been caught
1834 // earlier and routed to SkImageFilters::Empty() instead.
1835 SkASSERT(!fInputs.empty());
1836 if (fInputs.size() == 1) {
1837 SkASSERT(!fInputs[0].fSampleBounds.has_value() &&
1838 fInputs[0].fSampling == kDefaultSampling &&
1839 fInputs[0].fFlags == ShaderFlags::kNone);
1840 return fInputs[0].fImage;
1841 }
1842
1843 const auto mergedBounds = LayerSpace<SkIRect>::Union(
1844 (int) fInputs.size(),
1845 [this](int i) { return fInputs[i].fImage.layerBounds(); });
1846 const auto outputBounds = this->outputBounds(mergedBounds);
1847
1848 AutoSurface surface{fContext, outputBounds, PixelBoundary::kTransparent,
1849 /*renderInParameterSpace=*/false};
1850 if (surface) {
1851 for (const SampledFilterResult& input : fInputs) {
1852 SkASSERT(!input.fSampleBounds.has_value() &&
1853 input.fSampling == kDefaultSampling &&
1854 input.fFlags == ShaderFlags::kNone);
1855 input.fImage.draw(fContext, surface.device(), /*preserveDeviceState=*/true);
1856 }
1857 }
1858 return surface.snap();
1859}
bool empty() const
Definition SkTArray.h:194
VkSurfaceKHR surface
Definition main.cc:49

The documentation for this class was generated from the following files: