Flutter Engine
The Flutter Engine
SkBlurMaskFilterImpl.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
18#include "include/core/SkPath.h"
24#include "include/core/SkRect.h"
32#include "src/base/SkTLazy.h"
34#include "src/core/SkBlurMask.h"
36#include "src/core/SkDrawBase.h"
37#include "src/core/SkMask.h"
44
45#include <algorithm>
46#include <cstdint>
47#include <cstring>
48#include <utility>
49
51 : fSigma(sigma)
52 , fBlurStyle(style)
53 , fRespectCTM(respectCTM) {
54 SkASSERT(fSigma > 0);
55 SkASSERT((unsigned)style <= kLastEnum_SkBlurStyle);
56}
57
59 return SkMask::kA8_Format;
60}
61
63 if (this->ignoreXform()) {
64 return false;
65 }
66
67 if (rec) {
68 rec->fSigma = fSigma;
69 rec->fStyle = fBlurStyle;
70 }
71 return true;
72}
75 float sigma = fSigma;
76 if (this->ignoreXform()) {
77 // This is analogous to computeXformedSigma(), but it might be more correct to wrap the
78 // blur image filter in a local matrix with ctm^-1, or to control the skif::Mapping when
79 // the mask filter layer is restored. This is inaccurate when 'ctm' has skew or perspective
80 const float ctmScaleFactor = fSigma / ctm.mapRadius(fSigma);
81 sigma *= ctmScaleFactor;
82 }
83
84 // The null input image filter will be bound to the original coverage mask.
86 // Combine the original coverage mask (src) and the blurred coverage mask (dst)
87 switch(fBlurStyle) {
88 case kInner_SkBlurStyle: // dst = dst * src
89 // = 0 * src + src * dst
90 return SkImageFilters::Blend(SkBlendMode::kDstIn, std::move(filter), nullptr);
91 case kSolid_SkBlurStyle: // dst = src + dst - src * dst
92 // = 1 * src + (1 - src) * dst
93 return SkImageFilters::Blend(SkBlendMode::kSrcOver, std::move(filter), nullptr);
94 case kOuter_SkBlurStyle: // dst = dst * (1 - src)
95 // = 0 * src + (1 - src) * dst
96 return SkImageFilters::Blend(SkBlendMode::kDstOut, std::move(filter), nullptr);
98 return filter;
99 }
101}
102
104 constexpr SkScalar kMaxBlurSigma = SkIntToScalar(128);
105 SkScalar xformedSigma = this->ignoreXform() ? fSigma : ctm.mapRadius(fSigma);
106 return std::min(xformedSigma, kMaxBlurSigma);
107}
108
110 const SkMatrix& matrix,
111 SkIPoint* margin) const {
112 SkScalar sigma = this->computeXformedSigma(matrix);
113 return SkBlurMask::BoxBlur(dst, src, sigma, fBlurStyle, margin);
114}
115
116bool SkBlurMaskFilterImpl::filterRectMask(SkMaskBuilder* dst, const SkRect& r,
117 const SkMatrix& matrix,
118 SkIPoint* margin,
119 SkMaskBuilder::CreateMode createMode) const {
121
122 return SkBlurMask::BlurRect(sigma, dst, r, fBlurStyle, margin, createMode);
123}
124
125bool SkBlurMaskFilterImpl::filterRRectMask(SkMaskBuilder* dst, const SkRRect& r,
126 const SkMatrix& matrix,
127 SkIPoint* margin,
128 SkMaskBuilder::CreateMode createMode) const {
130
131 return SkBlurMask::BlurRRect(sigma, dst, r, fBlurStyle, margin, createMode);
132}
133
135 SkASSERT(mask != nullptr);
136
137 mask->bounds() = bounds.roundOut();
138 mask->rowBytes() = SkAlign4(mask->fBounds.width());
139 mask->format() = SkMask::kA8_Format;
140 const size_t size = mask->computeImageSize();
142 if (nullptr == mask->fImage) {
143 return false;
144 }
145 return true;
146}
147
148template <typename Proc> bool draw_into_mask(SkMaskBuilder* mask, const SkRect& bounds, Proc proc) {
149 if (!prepare_to_draw_into_mask(bounds, mask)) {
150 return false;
151 }
152
153 const int dx = mask->fBounds.fLeft;
154 const int dy = mask->fBounds.fTop;
155 SkRasterClip rclip(mask->fBounds);
156 rclip.setRect(mask->fBounds.makeOffset(-dx, -dy));
157
159 auto info = SkImageInfo::MakeA8(mask->fBounds.width(), mask->fBounds.height());
160 auto pm = SkPixmap(info, mask->fImage, mask->fRowBytes);
161
163
165 draw.fBlitterChooser = SkA8Blitter_Choose;
166 draw.fCTM = &ctm;
167 draw.fDst = pm;
168 draw.fRC = &rclip;
169
171 paint.setAntiAlias(true);
172
173 proc(draw, paint);
174 return true;
175}
176
177static bool draw_rects_into_mask(const SkRect rects[], int count, SkMaskBuilder* mask) {
178 return draw_into_mask(mask, rects[0], [&](SkDrawBase& draw, const SkPaint& paint) {
179 if (1 == count) {
180 draw.drawRect(rects[0], paint);
181 } else {
182 // todo: do I need a fast way to do this?
183 SkPath path = SkPathBuilder().addRect(rects[0])
184 .addRect(rects[1])
186 .detach();
187 draw.drawPath(path, paint);
188 }
189 });
190}
191
193 return draw_into_mask(mask, rrect.rect(), [&](SkDrawBase& draw, const SkPaint& paint) {
194 draw.drawRRect(rrect, paint);
195 });
196}
197
198static bool rect_exceeds(const SkRect& r, SkScalar v) {
199 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v ||
200 r.width() > v || r.height() > v;
201}
202
204 const size_t size = mask->computeTotalImageSize();
206 if (data) {
207 memcpy(data->writable_data(), mask->fImage, size);
209 mask->image() = (uint8_t*)data->writable_data();
210 }
211 return data;
212}
213
215 const SkRRect& rrect) {
216 return SkMaskCache::FindAndRef(sigma, style, rrect, mask);
217}
218
220 const SkRRect& rrect) {
222 if (cache) {
223 SkMaskCache::Add(sigma, style, rrect, *mask, cache);
224 }
225 return cache;
226}
227
229 const SkRect rects[], int count) {
230 return SkMaskCache::FindAndRef(sigma, style, rects, count, mask);
231}
232
234 const SkRect rects[], int count) {
236 if (cache) {
237 SkMaskCache::Add(sigma, style, rects, count, *mask, cache);
238 }
239 return cache;
240}
241
242static const bool c_analyticBlurRRect{true};
243
245SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& matrix,
246 const SkIRect& clipBounds,
247 SkTLazy<NinePatch>* patch) const {
248 SkASSERT(patch != nullptr);
249 switch (rrect.getType()) {
251 // Nothing to draw.
252 return kFalse_FilterReturn;
253
255 // We should have caught this earlier.
256 SkASSERT(false);
257 [[fallthrough]];
259 // The nine patch special case does not handle ovals, and we
260 // already have code for rectangles.
262
263 // These three can take advantage of this fast path.
267 break;
268 }
269
270 // TODO: report correct metrics for innerstyle, where we do not grow the
271 // total bounds, but we do need an inset the size of our blur-radius
272 if (kInner_SkBlurStyle == fBlurStyle) {
274 }
275
276 // TODO: take clipBounds into account to limit our coordinates up front
277 // for now, just skip too-large src rects (to take the old code path).
278 if (rect_exceeds(rrect.rect(), SkIntToScalar(32767))) {
280 }
281
282 SkIPoint margin;
283 SkMaskBuilder srcM(nullptr, rrect.rect().roundOut(), 0, SkMask::kA8_Format), dstM;
284
285 bool filterResult = false;
287 // special case for fast round rect blur
288 // don't actually do the blur the first time, just compute the correct size
289 filterResult = this->filterRRectMask(&dstM, rrect, matrix, &margin,
291 }
292
293 if (!filterResult) {
294 filterResult = this->filterMask(&dstM, srcM, matrix, &margin);
295 }
296
297 if (!filterResult) {
298 return kFalse_FilterReturn;
299 }
300
301 // Now figure out the appropriate width and height of the smaller round rectangle
302 // to stretch. It will take into account the larger radius per side as well as double
303 // the margin, to account for inner and outer blur.
308
309 const SkScalar leftUnstretched = std::max(UL.fX, LL.fX) + SkIntToScalar(2 * margin.fX);
310 const SkScalar rightUnstretched = std::max(UR.fX, LR.fX) + SkIntToScalar(2 * margin.fX);
311
312 // Extra space in the middle to ensure an unchanging piece for stretching. Use 3 to cover
313 // any fractional space on either side plus 1 for the part to stretch.
314 const SkScalar stretchSize = SkIntToScalar(3);
315
316 const SkScalar totalSmallWidth = leftUnstretched + rightUnstretched + stretchSize;
317 if (totalSmallWidth >= rrect.rect().width()) {
318 // There is no valid piece to stretch.
320 }
321
322 const SkScalar topUnstretched = std::max(UL.fY, UR.fY) + SkIntToScalar(2 * margin.fY);
323 const SkScalar bottomUnstretched = std::max(LL.fY, LR.fY) + SkIntToScalar(2 * margin.fY);
324
325 const SkScalar totalSmallHeight = topUnstretched + bottomUnstretched + stretchSize;
326 if (totalSmallHeight >= rrect.rect().height()) {
327 // There is no valid piece to stretch.
329 }
330
331 SkRect smallR = SkRect::MakeWH(totalSmallWidth, totalSmallHeight);
332
333 SkRRect smallRR;
334 SkVector radii[4];
338 radii[SkRRect::kLowerLeft_Corner] = LL;
339 smallRR.setRectRadii(smallR, radii);
340
341 const SkScalar sigma = this->computeXformedSigma(matrix);
342 SkTLazy<SkMask> cachedMask;
343 SkCachedData* cache = find_cached_rrect(&cachedMask, sigma, fBlurStyle, smallRR);
344 if (!cache) {
345 SkMaskBuilder filterM;
346 bool analyticBlurWorked = false;
348 analyticBlurWorked =
349 this->filterRRectMask(&filterM, smallRR, matrix, &margin,
351 }
352
353 if (!analyticBlurWorked) {
354 if (!draw_rrect_into_mask(smallRR, &srcM)) {
355 return kFalse_FilterReturn;
356 }
357 SkAutoMaskFreeImage amf(srcM.image());
358
359 if (!this->filterMask(&filterM, srcM, matrix, &margin)) {
360 return kFalse_FilterReturn;
361 }
362 }
363 cache = add_cached_rrect(&filterM, sigma, fBlurStyle, smallRR);
364 cachedMask.init(filterM);
365 }
366
367 SkIRect bounds = cachedMask->fBounds;
368 bounds.offsetTo(0, 0);
369 patch->init(SkMask{cachedMask->fImage, bounds, cachedMask->fRowBytes, cachedMask->fFormat},
370 dstM.fBounds,
371 SkIPoint{SkScalarCeilToInt(leftUnstretched) + 1,
372 SkScalarCeilToInt(topUnstretched) + 1},
373 cache); // transfer ownership to patch
374 return kTrue_FilterReturn;
375}
376
377// Use the faster analytic blur approach for ninepatch rects
378static const bool c_analyticBlurNinepatch{true};
379
381SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count,
382 const SkMatrix& matrix,
383 const SkIRect& clipBounds,
384 SkTLazy<NinePatch>* patch) const {
385 if (count < 1 || count > 2) {
387 }
388
389 // TODO: report correct metrics for innerstyle, where we do not grow the
390 // total bounds, but we do need an inset the size of our blur-radius
391 if (kInner_SkBlurStyle == fBlurStyle || kOuter_SkBlurStyle == fBlurStyle) {
393 }
394
395 // TODO: take clipBounds into account to limit our coordinates up front
396 // for now, just skip too-large src rects (to take the old code path).
397 if (rect_exceeds(rects[0], SkIntToScalar(32767))) {
399 }
400
401 SkIPoint margin;
402 SkMaskBuilder srcM(nullptr, rects[0].roundOut(), 0, SkMask::kA8_Format), dstM;
403
404 bool filterResult = false;
405 if (count == 1 && c_analyticBlurNinepatch) {
406 // special case for fast rect blur
407 // don't actually do the blur the first time, just compute the correct size
408 filterResult = this->filterRectMask(&dstM, rects[0], matrix, &margin,
410 } else {
411 filterResult = this->filterMask(&dstM, srcM, matrix, &margin);
412 }
413
414 if (!filterResult) {
415 return kFalse_FilterReturn;
416 }
417
418 /*
419 * smallR is the smallest version of 'rect' that will still guarantee that
420 * we get the same blur results on all edges, plus 1 center row/col that is
421 * representative of the extendible/stretchable edges of the ninepatch.
422 * Since our actual edge may be fractional we inset 1 more to be sure we
423 * don't miss any interior blur.
424 * x is an added pixel of blur, and { and } are the (fractional) edge
425 * pixels from the original rect.
426 *
427 * x x { x x .... x x } x x
428 *
429 * Thus, in this case, we inset by a total of 5 (on each side) beginning
430 * with our outer-rect (dstM.fBounds)
431 */
432 SkRect smallR[2];
434
435 // +2 is from +1 for each edge (to account for possible fractional edges
436 int smallW = dstM.fBounds.width() - srcM.fBounds.width() + 2;
437 int smallH = dstM.fBounds.height() - srcM.fBounds.height() + 2;
438 SkIRect innerIR;
439
440 if (1 == count) {
441 innerIR = srcM.fBounds;
442 center.set(smallW, smallH);
443 } else {
444 SkASSERT(2 == count);
445 rects[1].roundIn(&innerIR);
446 center.set(smallW + (innerIR.left() - srcM.fBounds.left()),
447 smallH + (innerIR.top() - srcM.fBounds.top()));
448 }
449
450 // +1 so we get a clean, stretchable, center row/col
451 smallW += 1;
452 smallH += 1;
453
454 // we want the inset amounts to be integral, so we don't change any
455 // fractional phase on the fRight or fBottom of our smallR.
456 const SkScalar dx = SkIntToScalar(innerIR.width() - smallW);
457 const SkScalar dy = SkIntToScalar(innerIR.height() - smallH);
458 if (dx < 0 || dy < 0) {
459 // we're too small, relative to our blur, to break into nine-patch,
460 // so we ask to have our normal filterMask() be called.
462 }
463
464 smallR[0].setLTRB(rects[0].left(), rects[0].top(),
465 rects[0].right() - dx, rects[0].bottom() - dy);
466 if (smallR[0].width() < 2 || smallR[0].height() < 2) {
468 }
469 if (2 == count) {
470 smallR[1].setLTRB(rects[1].left(), rects[1].top(),
471 rects[1].right() - dx, rects[1].bottom() - dy);
472 SkASSERT(!smallR[1].isEmpty());
473 }
474
475 const SkScalar sigma = this->computeXformedSigma(matrix);
476 SkTLazy<SkMask> cachedMask;
477 SkCachedData* cache = find_cached_rects(&cachedMask, sigma, fBlurStyle, smallR, count);
478 if (!cache) {
479 SkMaskBuilder filterM;
480 if (count > 1 || !c_analyticBlurNinepatch) {
481 if (!draw_rects_into_mask(smallR, count, &srcM)) {
482 return kFalse_FilterReturn;
483 }
484
485 SkAutoMaskFreeImage amf(srcM.image());
486
487 if (!this->filterMask(&filterM, srcM, matrix, &margin)) {
488 return kFalse_FilterReturn;
489 }
490 } else {
491 if (!this->filterRectMask(&filterM, smallR[0], matrix, &margin,
493 return kFalse_FilterReturn;
494 }
495 }
496 cache = add_cached_rects(&filterM, sigma, fBlurStyle, smallR, count);
497 cachedMask.init(filterM);
498 }
499 SkIRect bounds = cachedMask->fBounds;
500 bounds.offsetTo(0, 0);
501 patch->init(SkMask{cachedMask->fImage, bounds, cachedMask->fRowBytes, cachedMask->fFormat},
502 dstM.fBounds, center, cache); // transfer ownership to patch
503 return kTrue_FilterReturn;
504}
505
507 SkRect* dst) const {
508 // TODO: if we're doing kInner blur, should we return a different outset?
509 // i.e. pad == 0 ?
510
511 SkScalar pad = 3.0f * fSigma;
512
513 dst->setLTRB(src.fLeft - pad, src.fTop - pad,
514 src.fRight + pad, src.fBottom + pad);
515}
516
517sk_sp<SkFlattenable> SkBlurMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
518 const SkScalar sigma = buffer.readScalar();
519 SkBlurStyle style = buffer.read32LE(kLastEnum_SkBlurStyle);
520
521 uint32_t flags = buffer.read32LE(0x3); // historically we only recorded 2 bits
522 bool respectCTM = !(flags & 1); // historically we stored ignoreCTM in low bit
523
524 return SkMaskFilter::MakeBlur((SkBlurStyle)style, sigma, respectCTM);
525}
526
527void SkBlurMaskFilterImpl::flatten(SkWriteBuffer& buffer) const {
528 buffer.writeScalar(fSigma);
529 buffer.writeUInt(fBlurStyle);
530 buffer.writeUInt(!fRespectCTM); // historically we recorded ignoreCTM
531}
532
534
536 if (SkIsFinite(sigma) && sigma > 0) {
537 return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, respectCTM));
538 }
539 return nullptr;
540}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
static constexpr T SkAlign4(T x)
Definition: SkAlign.h:16
#define SkUNREACHABLE
Definition: SkAssert.h:135
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kDstIn
r = d * sa
@ kSrcOver
r = s + (1-sa)*d
@ kDstOut
r = d * (1-sa)
SkBlitter * SkA8Blitter_Choose(const SkPixmap &dst, const SkMatrix &ctm, const SkPaint &paint, SkArenaAlloc *alloc, bool drawCoverage, sk_sp< SkShader > clipShader, const SkSurfaceProps &)
static SkCachedData * find_cached_rects(SkTLazy< SkMask > *mask, SkScalar sigma, SkBlurStyle style, const SkRect rects[], int count)
static bool draw_rrect_into_mask(const SkRRect rrect, SkMaskBuilder *mask)
static bool rect_exceeds(const SkRect &r, SkScalar v)
static SkCachedData * add_cached_rrect(SkMaskBuilder *mask, SkScalar sigma, SkBlurStyle style, const SkRRect &rrect)
bool draw_into_mask(SkMaskBuilder *mask, const SkRect &bounds, Proc proc)
static bool draw_rects_into_mask(const SkRect rects[], int count, SkMaskBuilder *mask)
static SkCachedData * add_cached_rects(SkMaskBuilder *mask, SkScalar sigma, SkBlurStyle style, const SkRect rects[], int count)
static const bool c_analyticBlurRRect
static SkCachedData * copy_mask_to_cacheddata(SkMaskBuilder *mask)
static const bool c_analyticBlurNinepatch
void sk_register_blur_maskfilter_createproc()
static bool prepare_to_draw_into_mask(const SkRect &bounds, SkMaskBuilder *mask)
static SkCachedData * find_cached_rrect(SkTLazy< SkMask > *mask, SkScalar sigma, SkBlurStyle style, const SkRRect &rrect)
SkBlurStyle
Definition: SkBlurTypes.h:11
@ kOuter_SkBlurStyle
nothing inside, fuzzy outside
Definition: SkBlurTypes.h:14
@ kSolid_SkBlurStyle
solid inside, fuzzy outside
Definition: SkBlurTypes.h:13
@ kInner_SkBlurStyle
fuzzy inside, nothing outside
Definition: SkBlurTypes.h:15
@ kNormal_SkBlurStyle
fuzzy inside and outside
Definition: SkBlurTypes.h:12
@ kLastEnum_SkBlurStyle
Definition: SkBlurTypes.h:17
#define SK_REGISTER_FLATTENABLE(type)
static bool SkIsFinite(T x, Pack... values)
std::unique_ptr< uint8_t, SkFunctionObject< SkMaskBuilder::FreeImage > > SkAutoMaskFreeImage
Definition: SkMask.h:316
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define SkScalarCeilToInt(x)
Definition: SkScalar.h:36
#define SkIntToScalar(x)
Definition: SkScalar.h:57
static SkScalar center(float pos0, float pos1)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition: aaclip.cpp:27
void(* Proc)(SkCanvas *, const SkRect &, const SkPaint &)
Definition: blurrect.cpp:42
SkMask::Format getFormat() const override
bool asABlur(BlurRec *) const override
SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, bool respectCTM)
sk_sp< SkImageFilter > asImageFilter(const SkMatrix &ctm) const override
bool filterMask(SkMaskBuilder *dst, const SkMask &src, const SkMatrix &, SkIPoint *margin) const override
SkScalar computeXformedSigma(const SkMatrix &ctm) const
void computeFastBounds(const SkRect &, SkRect *) const override
static bool BlurRect(SkScalar sigma, SkMaskBuilder *dst, const SkRect &src, SkBlurStyle, SkIPoint *margin=nullptr, SkMaskBuilder::CreateMode createMode=SkMaskBuilder::kComputeBoundsAndRenderImage_CreateMode)
Definition: SkBlurMask.cpp:407
static bool BlurRRect(SkScalar sigma, SkMaskBuilder *dst, const SkRRect &src, SkBlurStyle, SkIPoint *margin=nullptr, SkMaskBuilder::CreateMode createMode=SkMaskBuilder::kComputeBoundsAndRenderImage_CreateMode)
Definition: SkBlurMask.cpp:504
static bool BoxBlur(SkMaskBuilder *dst, const SkMask &src, SkScalar sigma, SkBlurStyle style, SkIPoint *margin=nullptr)
Definition: SkBlurMask.cpp:116
static sk_sp< SkImageFilter > Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Blend(SkBlendMode mode, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground=nullptr, const CropRect &cropRect={})
static void Add(SkScalar sigma, SkBlurStyle style, const SkRRect &rrect, const SkMask &mask, SkCachedData *data, SkResourceCache *localCache=nullptr)
static SkCachedData * FindAndRef(SkScalar sigma, SkBlurStyle style, const SkRRect &rrect, SkTLazy< SkMask > *mask, SkResourceCache *localCache=nullptr)
Definition: SkMaskCache.cpp:88
static sk_sp< SkMaskFilter > MakeBlur(SkBlurStyle style, SkScalar sigma, bool respectCTM=true)
SkScalar mapRadius(SkScalar radius) const
Definition: SkMatrix.cpp:1170
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91
SkPathBuilder & addRect(const SkRect &, SkPathDirection, unsigned startIndex)
SkPathBuilder & setFillType(SkPathFillType ft)
Definition: SkPathBuilder.h:42
Definition: SkPath.h:59
Type getType() const
Definition: SkRRect.h:76
const SkRect & rect() const
Definition: SkRRect.h:264
SkVector radii(Corner corner) const
Definition: SkRRect.h:271
@ kOval_Type
non-zero width and height filled with radii
Definition: SkRRect.h:69
@ kSimple_Type
non-zero width and height with equal radii
Definition: SkRRect.h:70
@ kEmpty_Type
zero width or height
Definition: SkRRect.h:67
@ kNinePatch_Type
non-zero width and height with axis-aligned radii
Definition: SkRRect.h:71
@ kRect_Type
non-zero width and height, and zeroed radii
Definition: SkRRect.h:68
@ kComplex_Type
non-zero width and height with arbitrary radii
Definition: SkRRect.h:72
@ kUpperLeft_Corner
index of top-left corner radii
Definition: SkRRect.h:252
@ kLowerRight_Corner
index of bottom-right corner radii
Definition: SkRRect.h:254
@ kUpperRight_Corner
index of top-right corner radii
Definition: SkRRect.h:253
@ kLowerLeft_Corner
index of bottom-left corner radii
Definition: SkRRect.h:255
void setRectRadii(const SkRect &rect, const SkVector radii[4])
Definition: SkRRect.cpp:189
bool setRect(const SkIRect &)
static SkCachedData * NewCachedData(size_t bytes)
T * init(Args &&... args)
Definition: SkTLazy.h:45
const Paint & paint
Definition: color_source.cc:38
#define LR
Definition: constants_arm.h:32
float SkScalar
Definition: extension.cpp:12
FlutterSemanticsFlag flags
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
Optional< SkRect > bounds
Definition: SkRecords.h:189
SkRRect rrect
Definition: SkRecords.h:232
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
Definition: switches.h:191
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
int32_t height
int32_t width
int32_t fX
x-axis value
Definition: SkPoint_impl.h:29
int32_t fY
y-axis value
Definition: SkPoint_impl.h:30
Definition: SkRect.h:32
constexpr int32_t top() const
Definition: SkRect.h:120
constexpr int32_t height() const
Definition: SkRect.h:165
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
constexpr int32_t width() const
Definition: SkRect.h:158
constexpr SkIRect makeOffset(int32_t dx, int32_t dy) const
Definition: SkRect.h:300
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
constexpr int32_t left() const
Definition: SkRect.h:113
static SkImageInfo MakeA8(int width, int height)
static void FreeImage(void *image)
Definition: SkMask.cpp:57
@ kComputeBoundsAndRenderImage_CreateMode
compute bounds, alloc image and render into it
Definition: SkMask.h:301
@ kJustComputeBounds_CreateMode
compute bounds and return
Definition: SkMask.h:299
@ kZeroInit_Alloc
Definition: SkMask.h:293
Format & format()
Definition: SkMask.h:239
uint32_t & rowBytes()
Definition: SkMask.h:238
static uint8_t * AllocImage(size_t bytes, AllocType=kUninit_Alloc)
Definition: SkMask.cpp:45
SkIRect & bounds()
Definition: SkMask.h:237
uint8_t *& image()
Definition: SkMask.h:236
Definition: SkMask.h:25
const uint32_t fRowBytes
Definition: SkMask.h:43
Format
Definition: SkMask.h:26
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition: SkMask.h:28
uint8_t const *const fImage
Definition: SkMask.h:41
const SkIRect fBounds
Definition: SkMask.h:42
size_t computeTotalImageSize() const
Definition: SkMask.cpp:34
size_t computeImageSize() const
Definition: SkMask.cpp:30
const Format fFormat
Definition: SkMask.h:44
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165
SkScalar fBottom
larger y-axis bounds
Definition: extension.cpp:17
void roundIn(SkIRect *dst) const
Definition: SkRect.h:1266
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition: extension.cpp:16
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241
constexpr float height() const
Definition: SkRect.h:769
void setLTRB(float left, float top, float right, float bottom)
Definition: SkRect.h:865
constexpr float width() const
Definition: SkRect.h:762
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63