Flutter Engine
The Flutter Engine
SkDevice.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011 Google Inc.
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
8#include "src/core/SkDevice.h"
9
17#include "include/core/SkPath.h"
24#include "include/core/SkSpan.h"
29#include "include/private/chromium/Slug.h" // IWYU pragma: keep
35#include "src/core/SkMemset.h"
36#include "src/core/SkPathPriv.h"
37#include "src/core/SkRectPriv.h"
40#include "src/text/GlyphRun.h"
42
43#include <cstdint>
44
46 : fInfo(info)
47 , fSurfaceProps(surfaceProps) {
48 fDeviceToGlobal.setIdentity();
49 fGlobalToDevice.setIdentity();
50}
51
52void SkDevice::setDeviceCoordinateSystem(const SkM44& deviceToGlobal,
53 const SkM44& globalToDevice,
54 const SkM44& localToDevice,
55 int bufferOriginX,
56 int bufferOriginY) {
57 fDeviceToGlobal = deviceToGlobal;
58 fDeviceToGlobal.normalizePerspective();
59 fGlobalToDevice = globalToDevice;
60 fGlobalToDevice.normalizePerspective();
61
62 fLocalToDevice = localToDevice;
63 fLocalToDevice.normalizePerspective();
64 if (bufferOriginX | bufferOriginY) {
65 fDeviceToGlobal.preTranslate(bufferOriginX, bufferOriginY);
66 fGlobalToDevice.postTranslate(-bufferOriginX, -bufferOriginY);
67 fLocalToDevice.postTranslate(-bufferOriginX, -bufferOriginY);
68 }
69 fLocalToDevice33 = fLocalToDevice.asM33();
70 fLocalToDeviceDirty = true;
71}
72
73void SkDevice::setGlobalCTM(const SkM44& ctm) {
74 fLocalToDevice = ctm;
75 fLocalToDevice.normalizePerspective();
76 // Map from the global CTM state to this device's coordinate system.
77 fLocalToDevice.postConcat(fGlobalToDevice);
78 fLocalToDevice33 = fLocalToDevice.asM33();
79 fLocalToDeviceDirty = true;
80}
81
83 // pixelAligned is set to the identity + integer translation of the device-to-global matrix.
84 // If they are equal then the device is by definition pixel aligned.
85 SkM44 pixelAligned = SkM44();
86 pixelAligned.setRC(0, 3, SkScalarFloorToScalar(fDeviceToGlobal.rc(0, 3)));
87 pixelAligned.setRC(1, 3, SkScalarFloorToScalar(fDeviceToGlobal.rc(1, 3)));
88 return pixelAligned == fDeviceToGlobal;
89}
90
92 // getOrigin() is deprecated, the old origin has been moved into the fDeviceToGlobal matrix.
93 // This extracts the origin from the matrix, but asserts that a more complicated coordinate
94 // space hasn't been set of the device. This function can be removed once existing use cases
95 // have been updated to use the device-to-global matrix instead or have themselves been removed
96 // (e.g. Android's device-space clip regions are going away, and are not compatible with the
97 // generalized device coordinate system).
99 return SkIPoint::Make(SkScalarFloorToInt(fDeviceToGlobal.rc(0, 3)),
100 SkScalarFloorToInt(fDeviceToGlobal.rc(1, 3)));
101}
102
104 // To get the transform from this space to the other device's, transform from our space to
105 // global and then from global to the other device.
106 return (dstDevice.fGlobalToDevice * fDeviceToGlobal).asM33();
107}
108
109static inline bool is_int(float x) {
110 return x == (float) sk_float_round2int(x);
111}
112
114 const SkMatrix& localToDevice = this->localToDevice();
115 bool isNonTranslate = localToDevice.getType() & ~(SkMatrix::kTranslate_Mask);
116 bool complexPaint = paint.getStyle() != SkPaint::kFill_Style || paint.getMaskFilter() ||
117 paint.getPathEffect();
118 bool antiAlias = paint.isAntiAlias() && (!is_int(localToDevice.getTranslateX()) ||
120 if (isNonTranslate || complexPaint || antiAlias) {
121 SkPath path;
123 path.setIsVolatile(true);
124 return this->drawPath(path, paint, true);
125 }
126
128 while (!it.done()) {
129 this->drawRect(SkRect::Make(it.rect()), paint);
130 it.next();
131 }
132}
133
134void SkDevice::drawArc(const SkArc& arc, const SkPaint& paint) {
135 SkPath path;
136 bool isFillNoPathEffect = SkPaint::kFill_Style == paint.getStyle() && !paint.getPathEffect();
137 SkPathPriv::CreateDrawArcPath(&path, arc, isFillNoPathEffect);
138 this->drawPath(path, paint);
139}
140
142 const SkRRect& inner, const SkPaint& paint) {
143 SkPath path;
144 path.addRRect(outer);
145 path.addRRect(inner);
146 path.setFillType(SkPathFillType::kEvenOdd);
147 path.setIsVolatile(true);
148
149 this->drawPath(path, paint, true);
150}
151
152void SkDevice::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
153 const SkPoint texCoords[4], sk_sp<SkBlender> blender,
154 const SkPaint& paint) {
156 auto vertices = SkPatchUtils::MakeVertices(cubics, colors, texCoords, lod.width(), lod.height(),
157 this->imageInfo().colorSpace());
158 if (vertices) {
159 this->drawVertices(vertices.get(), std::move(blender), paint);
160 }
161}
162
164 const SkRect& dst, SkFilterMode filter, const SkPaint& paint) {
165 SkLatticeIter iter(lattice, dst);
166
167 SkRect srcR, dstR;
168 SkColor c;
169 bool isFixedColor = false;
171
172 while (iter.next(&srcR, &dstR, &isFixedColor, &c)) {
173 // TODO: support this fast-path for GPU images
174 if (isFixedColor || (srcR.width() <= 1.0f && srcR.height() <= 1.0f &&
175 image->readPixels(nullptr, info, &c, 4, srcR.fLeft, srcR.fTop))) {
176 // Fast draw with drawRect, if this is a patch containing a single color
177 // or if this is a patch containing a single pixel.
178 if (0 != c || !paint.isSrcOver()) {
179 SkPaint paintCopy(paint);
180 int alpha = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha()));
181 paintCopy.setColor(SkColorSetA(c, alpha));
182 this->drawRect(dstR, paintCopy);
183 }
184 } else {
185 this->drawImageRect(image, &srcR, dstR, SkSamplingOptions(filter), paint,
187 }
188 }
189}
190
191static SkPoint* quad_to_tris(SkPoint tris[6], const SkPoint quad[4]) {
192 tris[0] = quad[0];
193 tris[1] = quad[1];
194 tris[2] = quad[2];
195
196 tris[3] = quad[0];
197 tris[4] = quad[2];
198 tris[5] = quad[3];
199
200 return tris + 6;
201}
202
204 const SkRect tex[],
205 const SkColor colors[],
206 int quadCount,
207 sk_sp<SkBlender> blender,
208 const SkPaint& paint) {
209 const int triCount = quadCount << 1;
210 const int vertexCount = triCount * 3;
212 if (colors) {
214 }
216
217 SkPoint* vPos = builder.positions();
218 SkPoint* vTex = builder.texCoords();
219 SkColor* vCol = builder.colors();
220 for (int i = 0; i < quadCount; ++i) {
221 SkPoint tmp[4];
222 xform[i].toQuad(tex[i].width(), tex[i].height(), tmp);
223 vPos = quad_to_tris(vPos, tmp);
224
225 tex[i].toQuad(tmp);
226 vTex = quad_to_tris(vTex, tmp);
227
228 if (colors) {
229 SkOpts::memset32(vCol, colors[i], 6);
230 vCol += 6;
231 }
232 }
233 this->drawVertices(builder.detach().get(), std::move(blender), paint);
234}
235
239 paint.setColor4f(color);
240 paint.setBlendMode(mode);
241 paint.setAntiAlias(aa == SkCanvas::kAll_QuadAAFlags);
242
243 if (clip) {
244 // Draw the clip directly as a quad since it's a filled color with no local coords
246 clipPath.addPoly(clip, 4, true);
247 this->drawPath(clipPath, paint);
248 } else {
249 this->drawRect(r, paint);
250 }
251}
252
254 const SkPoint dstClips[], const SkMatrix preViewMatrices[],
256 SkCanvas::SrcRectConstraint constraint) {
257 SkASSERT(paint.getStyle() == SkPaint::kFill_Style);
258 SkASSERT(!paint.getPathEffect());
259
260 SkPaint entryPaint = paint;
261 const SkM44 baseLocalToDevice = this->localToDevice44();
262 int clipIndex = 0;
263 for (int i = 0; i < count; ++i) {
264 // TODO: Handle per-edge AA. Right now this mirrors the SkiaRenderer component of Chrome
265 // which turns off antialiasing unless all four edges should be antialiased. This avoids
266 // seaming in tiled composited layers.
267 entryPaint.setAntiAlias(images[i].fAAFlags == SkCanvas::kAll_QuadAAFlags);
268 entryPaint.setAlphaf(paint.getAlphaf() * images[i].fAlpha);
269
270 SkASSERT(images[i].fMatrixIndex < 0 || preViewMatrices);
271 if (images[i].fMatrixIndex >= 0) {
272 this->setLocalToDevice(baseLocalToDevice *
273 SkM44(preViewMatrices[images[i].fMatrixIndex]));
274 }
275
276 SkASSERT(!images[i].fHasClip || dstClips);
277 if (images[i].fHasClip) {
278 // Since drawImageRect requires a srcRect, the dst clip is implemented as a true clip
279 this->pushClipStack();
281 clipPath.addPoly(dstClips + clipIndex, 4, true);
282 this->clipPath(clipPath, SkClipOp::kIntersect, entryPaint.isAntiAlias());
283 clipIndex += 4;
284 }
285 this->drawImageRect(images[i].fImage.get(), &images[i].fSrcRect, images[i].fDstRect,
286 sampling, entryPaint, constraint);
287 if (images[i].fHasClip) {
288 this->popClipStack();
289 }
290 if (images[i].fMatrixIndex >= 0) {
291 this->setLocalToDevice(baseLocalToDevice);
292 }
293 }
294}
295
296///////////////////////////////////////////////////////////////////////////////////////////////////
297
298void SkDevice::drawDrawable(SkCanvas* canvas, SkDrawable* drawable, const SkMatrix* matrix) {
299 drawable->draw(canvas, matrix);
300}
301
302///////////////////////////////////////////////////////////////////////////////////////////////////
303
306void SkDevice::drawCoverageMask(const SkSpecialImage*, const SkMatrix& maskToDevice,
307 const SkSamplingOptions&, const SkPaint&) {
308 // This shouldn't be reached; SkCanvas will only call this if
309 // useDrawCoverageMaskForMaskFilters() is overridden to return true.
310 SK_ABORT("Must override if useDrawCoverageMaskForMaskFilters() is true");
311}
312
315sk_sp<SkSpecialImage> SkDevice::snapSpecial(const SkIRect&, bool forceCopy) { return nullptr; }
317 const SkISize& dstDims) {
318 return nullptr;
319}
321 return this->snapSpecial(SkIRect::MakeWH(this->width(), this->height()));
322}
323
325 SkColorType colorType) const {
327}
328
331 const SkPaint& paint) {
332 sk_sp<SkSpecialImage> deviceImage = device->snapSpecial();
333 if (deviceImage) {
334 // SkCanvas only calls drawDevice() when there are no filters (so the transform is pixel
335 // aligned). As such it can be drawn without clamping.
336 SkMatrix relativeTransform = device->getRelativeTransform(*this);
337 const bool strict = sampling != SkFilterMode::kNearest ||
338 !relativeTransform.isTranslate() ||
339 !SkScalarIsInt(relativeTransform.getTranslateX()) ||
340 !SkScalarIsInt(relativeTransform.getTranslateY());
341 this->drawSpecial(deviceImage.get(), relativeTransform, sampling, paint,
344 }
345}
346
350 const SkImageFilter* filter,
352 const SkPaint& paint) {
353 SkASSERT(!paint.getImageFilter() && !paint.getMaskFilter());
354
355 skif::LayerSpace<SkIRect> targetOutput = mapping.deviceToLayer(
357
358 if (colorType == kUnknown_SkColorType) {
360 }
361
363 skif::Context ctx{this->createImageFilteringBackend(src ? src->props() : this->surfaceProps(),
364 colorType),
365 mapping,
366 targetOutput,
368 this->imageInfo().colorSpace(),
369 &stats};
370
373 stats.reportStats();
374 if (result) {
375 SkMatrix deviceMatrixWithOffset = mapping.layerToDevice();
376 deviceMatrixWithOffset.preTranslate(offset.fX, offset.fY);
377 this->drawSpecial(result.get(), deviceMatrixWithOffset, sampling, paint);
378 }
379}
380
381///////////////////////////////////////////////////////////////////////////////////////////////////
382
384 SkPixmap tempStorage;
385 if (nullptr == pmap) {
386 pmap = &tempStorage;
387 }
388 return this->onAccessPixels(pmap);
389}
390
392 SkPixmap tempStorage;
393 if (nullptr == pmap) {
394 pmap = &tempStorage;
395 }
396 return this->onPeekPixels(pmap);
397}
398
399//////////////////////////////////////////////////////////////////////////////////////////
400
401static sk_sp<SkShader> make_post_inverse_lm(const SkShader* shader, const SkMatrix& lm) {
402 SkMatrix inverse_lm;
403 if (!shader || !lm.invert(&inverse_lm)) {
404 return nullptr;
405 }
406
407#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) // b/256873449
408 // Legacy impl for old concat order. This does not work for arbitrary shader DAGs (when there is
409 // no single leaf local matrix).
410
411 // LMs pre-compose. In order to push a post local matrix, we peel off any existing local matrix
412 // and set a new local matrix of inverse_lm * prev_local_matrix.
413 SkMatrix prev_local_matrix;
414 const auto nested_shader = as_SB(shader)->makeAsALocalMatrixShader(&prev_local_matrix);
415 if (nested_shader) {
416 // unfurl the shader
417 shader = nested_shader.get();
418 }
419
420 return shader->makeWithLocalMatrix(inverse_lm * prev_local_matrix);
421#endif
422
423 return shader->makeWithLocalMatrix(inverse_lm);
424}
425
427 const sktext::GlyphRunList& glyphRunList,
428 const SkPaint& paint) {
429 if (!this->localToDevice().isFinite()) {
430 return;
431 }
432
433 if (!glyphRunList.hasRSXForm()) {
434 this->onDrawGlyphRunList(canvas, glyphRunList, paint);
435 } else {
436 this->simplifyGlyphRunRSXFormAndRedraw(canvas, glyphRunList, paint);
437 }
438}
439
440void SkDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas,
441 const sktext::GlyphRunList& glyphRunList,
442 const SkPaint& paint) {
443 for (const sktext::GlyphRun& run : glyphRunList) {
444 if (run.scaledRotations().empty()) {
445 auto subList = glyphRunList.builder()->makeGlyphRunList(run, paint, {0, 0});
446 this->drawGlyphRunList(canvas, subList, paint);
447 } else {
448 SkPoint origin = glyphRunList.origin();
449 SkPoint sharedPos{0, 0}; // we're at the origin
450 SkGlyphID sharedGlyphID;
451 sktext::GlyphRun glyphRun {
452 run.font(),
453 SkSpan<const SkPoint>{&sharedPos, 1},
454 SkSpan<const SkGlyphID>{&sharedGlyphID, 1},
458 };
459
460 for (auto [i, glyphID, pos] : SkMakeEnumerate(run.source())) {
461 sharedGlyphID = glyphID;
462 auto [scos, ssin] = run.scaledRotations()[i];
463 SkRSXform rsxForm = SkRSXform::Make(scos, ssin, pos.x(), pos.y());
464 SkMatrix glyphToLocal;
465 glyphToLocal.setRSXform(rsxForm).postTranslate(origin.x(), origin.y());
466
467 // We want to rotate each glyph by the rsxform, but we don't want to rotate "space"
468 // (i.e. the shader that cares about the ctm) so we have to undo our little ctm
469 // trick with a localmatrixshader so that the shader draws as if there was no
470 // change to the ctm.
471 SkPaint invertingPaint{paint};
472 invertingPaint.setShader(make_post_inverse_lm(paint.getShader(), glyphToLocal));
473 SkAutoCanvasRestore acr(canvas, true);
474 canvas->concat(SkM44(glyphToLocal));
475 sktext::GlyphRunList subList =
476 glyphRunList.builder()->makeGlyphRunList(glyphRun, paint, {0, 0});
477 this->drawGlyphRunList(canvas, subList, invertingPaint);
478 }
479 }
480 }
481}
482
484 const sktext::GlyphRunList& glyphRunList, const SkPaint& paint) {
485 return nullptr;
486}
487
489 SK_ABORT("Slug drawing not supported.");
490}
491
492//////////////////////////////////////////////////////////////////////////////////////////
493
495 return nullptr;
496}
497
499 // If we're doing linear blending, then we can disable the gamma hacks.
500 // Otherwise, leave them on. In either case, we still want the contrast boost:
501 // TODO: Can we be even smarter about mask gamma based on the dest transfer function?
502 const SkColorSpace* const cs = fInfo.colorSpace();
503 if (cs && cs->gammaIsLinear()) {
505 } else {
507 }
508}
509
510//////////////////////////////////////////////////////////////////////////////////////////
511
513 : SkNoPixelsDevice(bounds, props, nullptr) {}
514
516 sk_sp<SkColorSpace> colorSpace)
518 std::move(colorSpace)), props) {
519 // this fails if we enable this assert: DiscardableImageMapTest.GetDiscardableImagesInRectMaxImage
520 //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0);
521
522 this->setOrigin(SkM44(), bounds.left(), bounds.top());
523 fClipStack.emplace_back(this->bounds(), /*isAA=*/false, /*isRect=*/true);
524}
525
527 // Resetting should only happen on the root SkNoPixelsDevice, so its device-to-global
528 // transform should be pixel aligned.
530 // We can only reset the device as long as its dimensions are not changing.
531 if (bounds.width() != this->width() || bounds.height() != this->height()) {
532 return false;
533 }
534
535 // And the canvas should have restored back to the original save count.
536 SkASSERT(fClipStack.size() == 1 && fClipStack[0].fDeferredSaveCount == 0);
537 // But in the event that the clip was modified w/o a save(), reset the tracking state
538 fClipStack[0].fClipBounds = this->bounds();
539 fClipStack[0].fIsAA = false;
540 fClipStack[0].fIsRect = true;
541
542 this->setOrigin(SkM44(), bounds.left(), bounds.top());
543 return true;
544}
545
547 SkASSERT(!fClipStack.empty());
548 fClipStack.back().fDeferredSaveCount++;
549}
550
552 SkASSERT(!fClipStack.empty());
553 if (fClipStack.back().fDeferredSaveCount > 0) {
554 fClipStack.back().fDeferredSaveCount--;
555 } else {
556 fClipStack.pop_back();
557 SkASSERT(!fClipStack.empty());
558 }
559}
560
561SkNoPixelsDevice::ClipState& SkNoPixelsDevice::writableClip() {
562 SkASSERT(!fClipStack.empty());
563 ClipState& current = fClipStack.back();
564 if (current.fDeferredSaveCount > 0) {
565 current.fDeferredSaveCount--;
566 // Stash current state in case 'current' moves during a resize
567 SkIRect bounds = current.fClipBounds;
568 bool aa = current.fIsAA;
569 bool rect = current.fIsRect;
570 return fClipStack.emplace_back(bounds, aa, rect);
571 } else {
572 return current;
573 }
574}
575
577 this->writableClip().op(op, this->localToDevice44(), rect,
578 aa, /*fillsBounds=*/true);
579}
580
582 this->writableClip().op(op, this->localToDevice44(), rrect.getBounds(),
583 aa, /*fillsBounds=*/rrect.isRect());
584}
585
587 // Toggle op if the path is inverse filled
588 if (path.isInverseFillType()) {
590 }
591 this->writableClip().op(op, this->localToDevice44(), path.getBounds(),
592 aa, /*fillsBounds=*/false);
593}
594
596 this->writableClip().op(op, this->globalToDevice(), SkRect::Make(globalRgn.getBounds()),
597 /*isAA=*/false, /*fillsBounds=*/globalRgn.isRect());
598}
599
600void SkNoPixelsDevice::onClipShader(sk_sp<SkShader> shader) {
601 this->writableClip().fIsRect = false;
602}
603
605 SkIRect deviceRect = SkMatrixPriv::MapRect(this->globalToDevice(), SkRect::Make(rect)).round();
606 if (!deviceRect.intersect(this->bounds())) {
607 deviceRect.setEmpty();
608 }
609 auto& clip = this->writableClip();
610 clip.fClipBounds = deviceRect;
611 clip.fIsRect = true;
612 clip.fIsAA = false;
613}
614
615void SkNoPixelsDevice::ClipState::op(SkClipOp op, const SkM44& transform, const SkRect& bounds,
616 bool isAA, bool fillsBounds) {
617 const bool isRect = fillsBounds && SkMatrixPriv::IsScaleTranslateAsM33(transform);
618 fIsAA |= isAA;
619
620 SkRect devBounds = bounds.isEmpty() ? SkRect::MakeEmpty()
621 : SkMatrixPriv::MapRect(transform, bounds);
622 if (op == SkClipOp::kIntersect) {
623 if (!fClipBounds.intersect(isAA ? devBounds.roundOut() : devBounds.round())) {
624 fClipBounds.setEmpty();
625 }
626 // A rectangular clip remains rectangular if the intersection is a rect
627 fIsRect &= isRect;
628 } else if (isRect) {
629 // Conservatively, we can leave the clip bounds unchanged and respect the difference op.
630 // But, if we're subtracting out an axis-aligned rectangle that fully spans our existing
631 // clip on an axis, we can shrink the clip bounds.
634 if (SkRectPriv::Subtract(fClipBounds, isAA ? devBounds.roundIn() : devBounds.round(),
635 &difference)) {
636 fClipBounds = difference;
637 } else {
638 // The difference couldn't be represented as a rect
639 fIsRect = false;
640 }
641 } else {
642 // A non-rect shape was applied
643 fIsRect = false;
644 }
645}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
SkPoint pos
static bool isFinite(const SkRect &r)
Definition: MathBench.cpp:230
kUnpremul_SkAlphaType
@ kUnknown_SkAlphaType
uninitialized
Definition: SkAlphaType.h:27
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkBlendMode
Definition: SkBlendMode.h:38
SkClipOp
Definition: SkClipOp.h:13
#define SkAlphaMul(value, alpha256)
Definition: SkColorPriv.h:34
static unsigned SkAlpha255To256(U8CPU alpha)
Definition: SkColorPriv.h:24
SkColorType
Definition: SkColorType.h:19
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
uint32_t SkColor
Definition: SkColor.h:37
static constexpr SkColor SkColorSetA(SkColor c, U8CPU a)
Definition: SkColor.h:82
#define SkColorGetA(color)
Definition: SkColor.h:61
static bool is_int(float x)
Definition: SkDevice.cpp:109
static sk_sp< SkShader > make_post_inverse_lm(const SkShader *shader, const SkMatrix &lm)
Definition: SkDevice.cpp:401
static SkPoint * quad_to_tris(SkPoint tris[6], const SkPoint quad[4])
Definition: SkDevice.cpp:191
constexpr SkEnumerate< Iter > SkMakeEnumerate(C &c)
Definition: SkEnumerate.h:102
#define sk_float_round2int(x)
static SkImageFilter_Base * as_IFB(SkImageFilter *filter)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static size_t difference(size_t minuend, size_t subtrahend)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
SkFilterMode
#define SkScalarFloorToScalar(x)
Definition: SkScalar.h:30
static bool SkScalarIsInt(SkScalar x)
Definition: SkScalar.h:80
#define SkScalarFloorToInt(x)
Definition: SkScalar.h:35
SkScalerContextFlags
SkShaderBase * as_SB(SkShader *shader)
Definition: SkShaderBase.h:412
uint16_t SkGlyphID
Definition: SkTypes.h:179
SrcRectConstraint
Definition: SkCanvas.h:1541
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition: SkCanvas.h:1542
@ kFast_SrcRectConstraint
sample outside bounds; faster
Definition: SkCanvas.h:1543
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
@ kAll_QuadAAFlags
Definition: SkCanvas.h:1665
bool gammaIsLinear() const
void drawFilteredImage(const skif::Mapping &mapping, SkSpecialImage *src, SkColorType ct, const SkImageFilter *, const SkSamplingOptions &, const SkPaint &)
Definition: SkDevice.cpp:347
const SkImageInfo & imageInfo() const
Definition: SkDevice.h:117
virtual void drawVertices(const SkVertices *, sk_sp< SkBlender >, const SkPaint &, bool skipColorXform=false)=0
virtual void drawEdgeAAQuad(const SkRect &rect, const SkPoint clip[4], SkCanvas::QuadAAFlags aaFlags, const SkColor4f &color, SkBlendMode mode)
Definition: SkDevice.cpp:236
SkScalerContextFlags scalerContextFlags() const
Definition: SkDevice.cpp:498
virtual void drawRegion(const SkRegion &r, const SkPaint &paint)
Definition: SkDevice.cpp:113
int height() const
Definition: SkDevice.h:120
SkIPoint getOrigin() const
Definition: SkDevice.cpp:91
SkDevice(const SkImageInfo &, const SkSurfaceProps &)
Definition: SkDevice.cpp:45
virtual void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp< SkBlender >, const SkPaint &)
Definition: SkDevice.cpp:203
virtual void clipPath(const SkPath &path, SkClipOp op, bool aa)=0
void setLocalToDevice(const SkM44 &localToDevice)
Definition: SkDevice.h:211
virtual bool onAccessPixels(SkPixmap *)
Definition: SkDevice.h:533
virtual void drawCoverageMask(const SkSpecialImage *, const SkMatrix &maskToDevice, const SkSamplingOptions &, const SkPaint &)
Definition: SkDevice.cpp:306
virtual sk_sp< skif::Backend > createImageFilteringBackend(const SkSurfaceProps &surfaceProps, SkColorType colorType) const
Definition: SkDevice.cpp:324
void drawGlyphRunList(SkCanvas *, const sktext::GlyphRunList &glyphRunList, const SkPaint &paint)
Definition: SkDevice.cpp:426
virtual void drawEdgeAAImageSet(const SkCanvas::ImageSetEntry[], int count, const SkPoint dstClips[], const SkMatrix preViewMatrices[], const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint)
Definition: SkDevice.cpp:253
const SkM44 & globalToDevice() const
Definition: SkDevice.h:191
virtual void drawDRRect(const SkRRect &outer, const SkRRect &inner, const SkPaint &)
Definition: SkDevice.cpp:141
sk_sp< SkSpecialImage > snapSpecial()
Definition: SkDevice.cpp:320
virtual void popClipStack()=0
virtual sk_sp< SkSpecialImage > snapSpecialScaled(const SkIRect &subset, const SkISize &dstDims)
Definition: SkDevice.cpp:316
virtual void pushClipStack()=0
bool accessPixels(SkPixmap *pmap)
Definition: SkDevice.cpp:383
const SkMatrix & localToDevice() const
Definition: SkDevice.h:179
virtual void drawSlug(SkCanvas *, const sktext::gpu::Slug *slug, const SkPaint &paint)
Definition: SkDevice.cpp:488
void setOrigin(const SkM44 &globalCTM, int x, int y)
Definition: SkDevice.h:508
virtual void drawSpecial(SkSpecialImage *, const SkMatrix &localToDevice, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint constraint=SkCanvas::kStrict_SrcRectConstraint)
Definition: SkDevice.cpp:304
bool isPixelAlignedToGlobal() const
Definition: SkDevice.cpp:82
virtual void drawDevice(SkDevice *, const SkSamplingOptions &, const SkPaint &)
Definition: SkDevice.cpp:329
virtual SkIRect devClipBounds() const =0
const SkSurfaceProps & surfaceProps() const
Definition: SkDevice.h:131
virtual bool onPeekPixels(SkPixmap *)
Definition: SkDevice.h:535
virtual sk_sp< SkSpecialImage > makeSpecial(const SkBitmap &)
Definition: SkDevice.cpp:313
const SkM44 & deviceToGlobal() const
Definition: SkDevice.h:186
virtual void drawDrawable(SkCanvas *, SkDrawable *, const SkMatrix *)
Definition: SkDevice.cpp:298
virtual void onDrawGlyphRunList(SkCanvas *, const sktext::GlyphRunList &, const SkPaint &paint)=0
void setDeviceCoordinateSystem(const SkM44 &deviceToGlobal, const SkM44 &globalToDevice, const SkM44 &localToDevice, int bufferOriginX, int bufferOriginY)
Definition: SkDevice.cpp:52
void setGlobalCTM(const SkM44 &ctm)
Definition: SkDevice.cpp:73
virtual sk_sp< sktext::gpu::Slug > convertGlyphRunListToSlug(const sktext::GlyphRunList &glyphRunList, const SkPaint &paint)
Definition: SkDevice.cpp:483
bool peekPixels(SkPixmap *)
Definition: SkDevice.cpp:391
virtual sk_sp< SkSurface > makeSurface(const SkImageInfo &, const SkSurfaceProps &)
Definition: SkDevice.cpp:494
int width() const
Definition: SkDevice.h:119
virtual void drawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], sk_sp< SkBlender >, const SkPaint &paint)
Definition: SkDevice.cpp:152
virtual void drawRect(const SkRect &r, const SkPaint &paint)=0
virtual void drawImageRect(const SkImage *, const SkRect *src, const SkRect &dst, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint)=0
const SkM44 & localToDevice44() const
Definition: SkDevice.h:178
SkIRect bounds() const
Definition: SkDevice.h:125
virtual void drawArc(const SkArc &arc, const SkPaint &paint)
Definition: SkDevice.cpp:134
virtual void drawPath(const SkPath &path, const SkPaint &paint, bool pathIsMutable=false)=0
SkMatrix getRelativeTransform(const SkDevice &) const
Definition: SkDevice.cpp:103
virtual void drawImageLattice(const SkImage *, const SkCanvas::Lattice &, const SkRect &dst, SkFilterMode, const SkPaint &)
Definition: SkDevice.cpp:163
void draw(SkCanvas *, const SkMatrix *=nullptr)
Definition: SkDrawable.cpp:43
skif::FilterResult filterImage(const skif::Context &context) const
bool readPixels(GrDirectContext *context, const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY, CachingHint cachingHint=kAllow_CachingHint) const
Definition: SkImage.cpp:42
bool next(SkIRect *src, SkRect *dst, bool *isFixedColor=nullptr, SkColor *fixedColor=nullptr)
Definition: SkM44.h:150
SkM44 & postConcat(const SkM44 &m)
Definition: SkM44.h:355
SkM44 & postTranslate(SkScalar x, SkScalar y, SkScalar z=0)
Definition: SkM44.cpp:100
void normalizePerspective()
Definition: SkM44.cpp:226
SkScalar rc(int r, int c) const
Definition: SkM44.h:261
SkMatrix asM33() const
Definition: SkM44.h:409
void setRC(int r, int c, SkScalar value)
Definition: SkM44.h:266
SkM44 & setIdentity()
Definition: SkM44.h:293
SkM44 & preTranslate(SkScalar x, SkScalar y, SkScalar z=0)
Definition: SkM44.cpp:89
static SkRect MapRect(const SkM44 &m, const SkRect &r)
Definition: SkM44.cpp:216
static bool IsScaleTranslateAsM33(const SkM44 &m)
Definition: SkMatrixPriv.h:190
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:281
SkScalar getTranslateY() const
Definition: SkMatrix.h:452
bool invert(SkMatrix *inverse) const
Definition: SkMatrix.h:1206
bool isTranslate() const
Definition: SkMatrix.h:248
SkMatrix & setRSXform(const SkRSXform &rsxForm)
Definition: SkMatrix.cpp:420
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:263
SkScalar getTranslateX() const
Definition: SkMatrix.h:445
@ kTranslate_Mask
translation SkMatrix
Definition: SkMatrix.h:193
TypeMask getType() const
Definition: SkMatrix.h:207
void clipRegion(const SkRegion &globalRgn, SkClipOp op) override
Definition: SkDevice.cpp:595
void clipRect(const SkRect &rect, SkClipOp op, bool aa) override
Definition: SkDevice.cpp:576
bool resetForNextPicture(const SkIRect &bounds)
Definition: SkDevice.cpp:526
void popClipStack() override
Definition: SkDevice.cpp:551
void replaceClip(const SkIRect &rect) override
Definition: SkDevice.cpp:604
void clipPath(const SkPath &path, SkClipOp op, bool aa) override
Definition: SkDevice.cpp:586
void pushClipStack() override
Definition: SkDevice.cpp:546
SkNoPixelsDevice(const SkIRect &bounds, const SkSurfaceProps &props)
Definition: SkDevice.cpp:512
void clipRRect(const SkRRect &rrect, SkClipOp op, bool aa) override
Definition: SkDevice.cpp:581
void setColor(SkColor color)
Definition: SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition: SkPaint.h:170
@ kFill_Style
set to fill geometry
Definition: SkPaint.h:193
bool isAntiAlias() const
Definition: SkPaint.h:162
void setAlphaf(float a)
Definition: SkPaint.cpp:130
static sk_sp< SkVertices > MakeVertices(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], int lodX, int lodY, SkColorSpace *colorSpace=nullptr)
static SkISize GetLevelOfDetail(const SkPoint cubics[12], const SkMatrix *matrix)
static void CreateDrawArcPath(SkPath *path, const SkArc &arc, bool isFillNoPathEffect)
Definition: SkPath.cpp:3356
Definition: SkPath.h:59
const SkRect & getBounds() const
Definition: SkPath.cpp:430
bool isRect() const
Definition: SkRRect.h:84
const SkRect & getBounds() const
Definition: SkRRect.h:279
static bool Subtract(const SkRect &a, const SkRect &b, SkRect *out)
Definition: SkRect.cpp:252
const SkIRect & rect() const
Definition: SkRegion.h:501
bool done() const
Definition: SkRegion.h:488
bool getBoundaryPath(SkPath *path) const
bool isRect() const
Definition: SkRegion.h:152
const SkIRect & getBounds() const
Definition: SkRegion.h:165
virtual sk_sp< SkShader > makeAsALocalMatrixShader(SkMatrix *localMatrix) const
sk_sp< SkShader > makeWithLocalMatrix(const SkMatrix &) const
Definition: SkShader.cpp:26
sk_sp< SkVertices > detach()
Definition: SkVertices.cpp:146
@ kHasTexCoords_BuilderFlag
Definition: SkVertices.h:63
@ kHasColors_BuilderFlag
Definition: SkVertices.h:64
@ kTriangles_VertexMode
Definition: SkVertices.h:31
T * get() const
Definition: SkRefCnt.h:303
bool empty() const
Definition: SkTArray.h:199
int size() const
Definition: SkTArray.h:421
T & emplace_back(Args &&... args)
Definition: SkTArray.h:248
sk_sp< SkSpecialImage > imageAndOffset(const Context &ctx, SkIPoint *offset) const
const SkMatrix & deviceToLayer() const
const SkMatrix & layerToDevice() const
GlyphRunList makeGlyphRunList(const GlyphRun &run, const SkPaint &paint, SkPoint origin)
Definition: GlyphRun.cpp:189
bool hasRSXForm() const
Definition: GlyphRun.h:105
GlyphRunBuilder * builder() const
Definition: GlyphRun.h:118
const Paint & paint
Definition: color_source.cc:38
DlColor color
VkDevice device
Definition: main.cc:53
FlutterSemanticsFlag flags
GAsyncResult * result
std::array< MockImage, 3 > images
Definition: mock_vulkan.cc:41
double x
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
void(* memset32)(uint32_t[], uint32_t, int)
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
Optional< SkRect > bounds
Definition: SkRecords.h:189
PODArray< SkPoint > dstClips
Definition: SkRecords.h:364
sk_sp< const SkImage > image
Definition: SkRecords.h:269
ClipOpAndAA opAA SkRegion region
Definition: SkRecords.h:238
SkRRect rrect
Definition: SkRecords.h:232
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
PODArray< SkMatrix > preViewMatrices
Definition: SkRecords.h:365
PODArray< SkColor > colors
Definition: SkRecords.h:276
SkSamplingOptions sampling
Definition: SkRecords.h:337
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
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 mode
Definition: switches.h:228
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
dictionary stats
Definition: malisc.py:20
Definition: run.py:1
SkSamplingOptions(SkFilterMode::kLinear))
sk_sp< Backend > MakeRasterBackend(const SkSurfaceProps &surfaceProps, SkColorType colorType)
Definition: ref_ptr.h:256
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47
SeparatedVector2 offset
Definition: SkArc.h:15
static constexpr SkIPoint Make(int32_t x, int32_t y)
Definition: SkPoint_impl.h:38
Definition: SkRect.h:32
bool intersect(const SkIRect &r)
Definition: SkRect.h:513
constexpr int32_t top() const
Definition: SkRect.h:120
constexpr int32_t height() const
Definition: SkRect.h:165
constexpr int32_t width() const
Definition: SkRect.h:158
void setEmpty()
Definition: SkRect.h:242
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56
constexpr int32_t left() const
Definition: SkRect.h:113
Definition: SkSize.h:16
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
SkColorSpace * colorSpace() const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
constexpr float y() const
Definition: SkPoint_impl.h:187
constexpr float x() const
Definition: SkPoint_impl.h:181
void toQuad(SkScalar width, SkScalar height, SkPoint quad[4]) const
Definition: SkRSXform.cpp:9
static SkRSXform Make(SkScalar scos, SkScalar ssin, SkScalar tx, SkScalar ty)
Definition: SkRSXform.h:24
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
static constexpr SkRect MakeEmpty()
Definition: SkRect.h:595
void toQuad(SkPoint quad[4]) const
Definition: SkRect.cpp:50
void roundIn(SkIRect *dst) const
Definition: SkRect.h:1266
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241
void round(SkIRect *dst) const
Definition: SkRect.h:1228
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15