Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
AutoLayerForImageFilter Class Reference

#include <SkCanvasPriv.h>

Public Member Functions

 AutoLayerForImageFilter (SkCanvas *canvas, const SkPaint &paint, const SkRect *rawBounds, bool skipMaskFilterLayer)
 
 AutoLayerForImageFilter (const AutoLayerForImageFilter &)=delete
 
AutoLayerForImageFilteroperator= (const AutoLayerForImageFilter &)=delete
 
 AutoLayerForImageFilter (AutoLayerForImageFilter &&)
 
AutoLayerForImageFilteroperator= (AutoLayerForImageFilter &&)
 
 ~AutoLayerForImageFilter ()
 
const SkPaintpaint () const
 
void addMaskFilterLayer (const SkRect *drawBounds)
 

Detailed Description

We implement ImageFilters and MaskFilters for a given draw by creating a layer, then applying the filter to the pixels of that layer (its backing surface/image), and then we call restore() to blend that layer to the main canvas.

If the paint has neither an image filter nor a mask filter, there will be no layer and paint() returns the original without modification.

NOTE: This works by assuming all sources of color and shading are represented by the SkPaint. Operations like drawImageRect must convert to an equivalent drawRect call if there's a mask filter, or otherwise ensure there are no mask filters (e.g. drawAtlas).

Definition at line 122 of file SkCanvasPriv.h.

Constructor & Destructor Documentation

◆ AutoLayerForImageFilter() [1/3]

AutoLayerForImageFilter::AutoLayerForImageFilter ( SkCanvas canvas,
const SkPaint paint,
const SkRect rawBounds,
bool  skipMaskFilterLayer 
)

Definition at line 162 of file SkCanvasPriv.cpp.

166 : fPaint(paint)
167 , fCanvas(canvas)
168 , fTempLayersForFilters(0) {
169 SkDEBUGCODE(fSaveCount = canvas->getSaveCount();)
170
171 // Depending on the original paint, this will add 0, 1, or 2 layers that apply the
172 // filter effects to a temporary layer that rasterized the remaining effects. Image filters
173 // are applied to the result of any mask filter, so its layer is added first in the stack.
174 //
175 // If present on the original paint, the image filter layer's restore paint steals the blender
176 // and the image filter so that the draw's paint will never have an image filter.
177 if (fPaint.getImageFilter() && !SkCanvasPriv::ImageToColorFilter(&fPaint)) {
178 this->addImageFilterLayer(rawBounds);
179 }
180
181 // If present on the original paint, the mask filter layer's restore paint steals all shading
182 // effects and the draw's paint shading is updated to draw a solid opaque color (thus encoding
183 // coverage into the alpha channel). The draw's paint preserves all geometric effects that have
184 // to be applied before the mask filter. The layer's restore paint adds an image filter
185 // representing the mask filter.
186 if (fPaint.getMaskFilter() && !skipMaskFilterLayer) {
187 this->addMaskFilterLayer(rawBounds);
188 }
189
190 // When the original paint has both an image filter and a mask filter, this will create two
191 // internal layers and perform two restores when finished. This actually creates one fewer
192 // offscreen passes compared to directly composing the mask filter's output with an
193 // SkImageFilters::Shader node and passing that into the rest of the image filter.
194}
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
void addMaskFilterLayer(const SkRect *drawBounds)
const SkPaint & paint() const
Definition: SkCanvasPriv.h:144
int getSaveCount() const
Definition: SkCanvas.cpp:431
SkMaskFilter * getMaskFilter() const
Definition: SkPaint.h:534
if(end==-1)

◆ AutoLayerForImageFilter() [2/3]

AutoLayerForImageFilter::AutoLayerForImageFilter ( const AutoLayerForImageFilter )
delete

◆ AutoLayerForImageFilter() [3/3]

AutoLayerForImageFilter::AutoLayerForImageFilter ( AutoLayerForImageFilter &&  other)

Definition at line 205 of file SkCanvasPriv.cpp.

205 {
206 *this = std::move(other);
207}

◆ ~AutoLayerForImageFilter()

AutoLayerForImageFilter::~AutoLayerForImageFilter ( )

Definition at line 196 of file SkCanvasPriv.cpp.

196 {
197 for (int i = 0; i < fTempLayersForFilters; ++i) {
198 fCanvas->fSaveCount -= 1;
199 fCanvas->internalRestore();
200 }
201 // Negative save count occurs when this layer was moved.
202 SkASSERT(fSaveCount < 0 || fCanvas->getSaveCount() == fSaveCount);
203}
#define SkASSERT(cond)
Definition: SkAssert.h:116

Member Function Documentation

◆ addMaskFilterLayer()

void AutoLayerForImageFilter::addMaskFilterLayer ( const SkRect drawBounds)

Definition at line 241 of file SkCanvasPriv.cpp.

241 {
242 // Shouldn't be adding a layer if there was no mask filter to begin with.
243 SkASSERT(fPaint.getMaskFilter());
244
245 // Image filters are evaluated after mask filters so any filter should have been converted to
246 // a layer and removed from fPaint already.
247 SkASSERT(!fPaint.getImageFilter());
248
249 // TODO: Eventually all SkMaskFilters will implement this method so this can switch to an assert
250 sk_sp<SkImageFilter> maskFilterAsImageFilter =
251 as_MFB(fPaint.getMaskFilter())->asImageFilter(fCanvas->getTotalMatrix());
252 if (!maskFilterAsImageFilter) {
253 // This is a legacy mask filter that can be handled by raster and Ganesh directly, but will
254 // be ignored by Graphite. Return now, leaving the paint with the mask filter so that the
255 // underlying SkDevice can handle it if it will.
256 return;
257 }
258
259 // The restore paint for the coverage layer takes over all shading effects that had been on the
260 // original paint, which will be applied to the alpha-only output image from the mask filter
261 // converted to an image filter.
262 SkPaint restorePaint;
263 restorePaint.setColor4f(fPaint.getColor4f());
264 restorePaint.setShader(fPaint.refShader());
265 restorePaint.setColorFilter(fPaint.refColorFilter());
266 restorePaint.setBlender(fPaint.refBlender());
267 restorePaint.setDither(fPaint.isDither());
268 restorePaint.setImageFilter(maskFilterAsImageFilter);
269
270 // Remove all shading effects from the "working" paint so that the layer's alpha channel
271 // will correspond to the coverage. This leaves the original style and AA settings that
272 // contribute to coverage (including any path effect).
274 fPaint.setShader(nullptr);
275 fPaint.setColorFilter(nullptr);
276 fPaint.setMaskFilter(nullptr);
277 fPaint.setDither(false);
279
280 this->addLayer(restorePaint, drawBounds, /*coverageOnly=*/true);
281}
@ kSrcOver
r = s + (1-sa)*d
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)
SkMatrix getTotalMatrix() const
Definition: SkCanvas.cpp:1629
virtual sk_sp< SkImageFilter > asImageFilter(const SkMatrix &ctm) const
sk_sp< SkShader > refShader() const
void setDither(bool dither)
Definition: SkPaint.h:182
void setImageFilter(sk_sp< SkImageFilter > imageFilter)
bool isDither() const
Definition: SkPaint.h:175
sk_sp< SkColorFilter > refColorFilter() const
void setColor4f(const SkColor4f &color, SkColorSpace *colorSpace=nullptr)
Definition: SkPaint.h:253
void setMaskFilter(sk_sp< SkMaskFilter > maskFilter)
SkColor4f getColor4f() const
Definition: SkPaint.h:232
sk_sp< SkBlender > refBlender() const
void setShader(sk_sp< SkShader > shader)
void setBlendMode(SkBlendMode mode)
Definition: SkPaint.cpp:151
SkImageFilter * getImageFilter() const
Definition: SkPaint.h:564
void setColorFilter(sk_sp< SkColorFilter > colorFilter)
void setBlender(sk_sp< SkBlender > blender)
Definition: SkPaint.cpp:155
constexpr SkColor4f kWhite
Definition: SkColor.h:439

◆ operator=() [1/2]

AutoLayerForImageFilter & AutoLayerForImageFilter::operator= ( AutoLayerForImageFilter &&  other)

Definition at line 209 of file SkCanvasPriv.cpp.

209 {
210 fPaint = std::move(other.fPaint);
211 fCanvas = other.fCanvas;
212 fTempLayersForFilters = other.fTempLayersForFilters;
213 SkDEBUGCODE(fSaveCount = other.fSaveCount;)
214
215 other.fTempLayersForFilters = 0;
216 SkDEBUGCODE(other.fSaveCount = -1;)
217
218 return *this;
219}

◆ operator=() [2/2]

AutoLayerForImageFilter & AutoLayerForImageFilter::operator= ( const AutoLayerForImageFilter )
delete

◆ paint()

const SkPaint & AutoLayerForImageFilter::paint ( ) const
inline

Definition at line 144 of file SkCanvasPriv.h.

144{ return fPaint; }

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