Flutter Engine
The Flutter Engine
Device_drawTexture.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 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
9
14#include "src/core/SkDraw.h"
25#include "src/gpu/ganesh/SkGr.h"
35
36using namespace skia_private;
37
38namespace {
39
40inline bool use_shader(bool textureIsAlphaOnly, const SkPaint& paint) {
41 return textureIsAlphaOnly && paint.getShader();
42}
43
44//////////////////////////////////////////////////////////////////////////////
45// Helper functions for dropping src rect subset with GrSamplerState::Filter::kLinear.
46
47static const SkScalar kColorBleedTolerance = 0.001f;
48
49bool has_aligned_samples(const SkRect& srcRect, const SkRect& transformedRect) {
50 // detect pixel disalignment
51 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - transformedRect.left()) < kColorBleedTolerance &&
52 SkScalarAbs(SkScalarRoundToScalar(transformedRect.top()) - transformedRect.top()) < kColorBleedTolerance &&
53 SkScalarAbs(transformedRect.width() - srcRect.width()) < kColorBleedTolerance &&
54 SkScalarAbs(transformedRect.height() - srcRect.height()) < kColorBleedTolerance) {
55 return true;
56 }
57 return false;
58}
59
60bool may_color_bleed(const SkRect& srcRect,
61 const SkRect& transformedRect,
62 const SkMatrix& m,
63 int numSamples) {
64 // Only gets called if has_aligned_samples returned false.
65 // So we can assume that sampling is axis aligned but not texel aligned.
66 SkASSERT(!has_aligned_samples(srcRect, transformedRect));
67 SkRect innerSrcRect(srcRect), innerTransformedRect, outerTransformedRect(transformedRect);
68 if (numSamples > 1) {
69 innerSrcRect.inset(SK_Scalar1, SK_Scalar1);
70 } else {
71 innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf);
72 }
73 m.mapRect(&innerTransformedRect, innerSrcRect);
74
75 // The gap between outerTransformedRect and innerTransformedRect
76 // represents the projection of the source border area, which is
77 // problematic for color bleeding. We must check whether any
78 // destination pixels sample the border area.
79 outerTransformedRect.inset(kColorBleedTolerance, kColorBleedTolerance);
80 innerTransformedRect.outset(kColorBleedTolerance, kColorBleedTolerance);
81 SkIRect outer, inner;
82 outerTransformedRect.round(&outer);
83 innerTransformedRect.round(&inner);
84 // If the inner and outer rects round to the same result, it means the
85 // border does not overlap any pixel centers. Yay!
86 return inner != outer;
87}
88
89bool can_ignore_linear_filtering_subset(const SkRect& srcSubset,
90 const SkMatrix& srcRectToDeviceSpace,
91 int numSamples) {
92 if (srcRectToDeviceSpace.rectStaysRect()) {
93 // sampling is axis-aligned
94 SkRect transformedRect;
95 srcRectToDeviceSpace.mapRect(&transformedRect, srcSubset);
96
97 if (has_aligned_samples(srcSubset, transformedRect) ||
98 !may_color_bleed(srcSubset, transformedRect, srcRectToDeviceSpace, numSamples)) {
99 return true;
100 }
101 }
102 return false;
103}
104
105//////////////////////////////////////////////////////////////////////////////
106// Helper functions for drawing an image with ganesh::SurfaceDrawContext
107
108/**
109 * Checks whether the paint is compatible with using SurfaceDrawContext::drawTexture. It is more
110 * efficient than the SkImage general case.
111 */
112bool can_use_draw_texture(const SkPaint& paint, const SkSamplingOptions& sampling) {
113 return (!paint.getColorFilter() && !paint.getShader() && !paint.getMaskFilter() &&
114 !paint.getImageFilter() && !paint.getBlender() && !sampling.isAniso() &&
116}
117
118SkPMColor4f texture_color(SkColor4f paintColor, float entryAlpha, GrColorType srcColorType,
119 const GrColorInfo& dstColorInfo) {
120 paintColor.fA *= entryAlpha;
121 if (GrColorTypeIsAlphaOnly(srcColorType)) {
122 return SkColor4fPrepForDst(paintColor, dstColorInfo).premul();
123 } else {
124 float paintAlpha = SkTPin(paintColor.fA, 0.f, 1.f);
125 return { paintAlpha, paintAlpha, paintAlpha, paintAlpha };
126 }
127}
128
129// Assumes srcRect and dstRect have already been optimized to fit the proxy
131 const GrClip* clip,
132 const SkMatrix& ctm,
133 const SkPaint& paint,
135 const SkRect& srcRect,
136 const SkRect& dstRect,
137 const SkPoint dstClip[4],
138 GrQuadAAFlags aaFlags,
141 const GrColorInfo& srcColorInfo) {
142 if (GrColorTypeIsAlphaOnly(srcColorInfo.colorType())) {
143 view.concatSwizzle(skgpu::Swizzle("aaaa"));
144 }
145 const GrColorInfo& dstInfo = sdc->colorInfo();
146 auto textureXform = GrColorSpaceXform::Make(srcColorInfo, sdc->colorInfo());
147 GrSurfaceProxy* proxy = view.proxy();
148 // Must specify the strict constraint when the proxy is not functionally exact and the src
149 // rect would access pixels outside the proxy's content area without the constraint.
150 if (constraint != SkCanvas::kStrict_SrcRectConstraint && !proxy->isFunctionallyExact()) {
151 // Conservative estimate of how much a coord could be outset from src rect:
152 // 1/2 pixel for AA and 1/2 pixel for linear filtering
153 float buffer = 0.5f * (aaFlags != GrQuadAAFlags::kNone) +
155 SkRect safeBounds = proxy->getBoundsRect();
156 safeBounds.inset(buffer, buffer);
157 if (!safeBounds.contains(srcRect)) {
159 }
160 }
161
162 SkPMColor4f color = texture_color(paint.getColor4f(), 1.f, srcColorInfo.colorType(), dstInfo);
163 if (dstClip) {
164 // Get source coords corresponding to dstClip
165 SkPoint srcQuad[4];
166 GrMapRectPoints(dstRect, srcRect, dstClip, srcQuad, 4);
167
169 std::move(view),
170 srcColorInfo.colorType(),
171 srcColorInfo.alphaType(),
172 filter,
174 paint.getBlendMode_or(SkBlendMode::kSrcOver),
175 color,
176 srcQuad,
177 dstClip,
178 aaFlags,
179 constraint == SkCanvas::kStrict_SrcRectConstraint ? &srcRect : nullptr,
180 ctm,
181 std::move(textureXform));
182 } else {
183 sdc->drawTexture(clip,
184 std::move(view),
185 srcColorInfo.alphaType(),
186 filter,
188 paint.getBlendMode_or(SkBlendMode::kSrcOver),
189 color,
190 srcRect,
191 dstRect,
192 aaFlags,
193 constraint,
194 ctm,
195 std::move(textureXform));
196 }
197}
198
199SkFilterMode downgrade_to_filter(const SkSamplingOptions& sampling) {
202 // if we were "fancier" than just bilerp, only do bilerp
203 filter = SkFilterMode::kLinear;
204 }
205 return filter;
206}
207
208} // anonymous namespace
209
210
211//////////////////////////////////////////////////////////////////////////////
212
213namespace skgpu::ganesh {
214
216 const SkRect& src,
217 const SkRect& dst,
218 const SkPoint dstClip[4],
219 SkCanvas::QuadAAFlags canvasAAFlags,
220 const SkMatrix& localToDevice,
222 const SkPaint& paint,
224 const SkMatrix& srcToDst,
225 SkTileMode tm) {
226 GrRecordingContext* rContext = fContext.get();
227 SurfaceDrawContext* sdc = fSurfaceDrawContext.get();
228 const GrClip* clip = this->clip();
229
230 GrQuadAAFlags aaFlags = SkToGrQuadAAFlags(canvasAAFlags);
231 auto ib = as_IB(image);
232 if (tm == SkTileMode::kClamp && !ib->isYUVA() && can_use_draw_texture(paint, sampling)) {
233 // We've done enough checks above to allow us to pass ClampNearest() and not check for
234 // scaling adjustments.
235 auto [view, ct] = skgpu::ganesh::AsView(rContext, image, skgpu::Mipmapped::kNo);
236 if (!view) {
237 return;
238 }
240 info = info.makeColorType(ct);
241 draw_texture(sdc,
242 clip,
244 paint,
246 src,
247 dst,
248 dstClip,
249 aaFlags,
250 constraint,
251 std::move(view),
252 info);
253 return;
254 }
255
256 const SkMaskFilter* mf = paint.getMaskFilter();
257
258 // The shader expects proper local coords, so we can't replace local coords with texture coords
259 // if the shader will be used. If we have a mask filter we will change the underlying geometry
260 // that is rendered.
261 bool canUseTextureCoordsAsLocalCoords = !use_shader(image->isAlphaOnly(), paint) && !mf;
262
263 // Specifying the texture coords as local coordinates is an attempt to enable more GrDrawOp
264 // combining by not baking anything about the srcRect, dstRect, or ctm, into the texture
265 // FP. In the future this should be an opaque optimization enabled by the combination of
266 // GrDrawOp/GP and FP.
268 mf = nullptr;
269 }
270
271 bool restrictToSubset = SkCanvas::kStrict_SrcRectConstraint == constraint;
272
273 // If we have to outset for AA then we will generate texture coords outside the src rect. The
274 // same happens for any mask filter that extends the bounds rendered in the dst.
275 // This is conservative as a mask filter does not have to expand the bounds rendered.
276 bool coordsAllInsideSrcRect = aaFlags == GrQuadAAFlags::kNone && !mf;
277
278 // Check for optimization to drop the src rect constraint when using linear filtering.
279 // TODO: Just rely on image to handle this.
281 restrictToSubset && sampling.mipmap == SkMipmapMode::kNone && coordsAllInsideSrcRect &&
282 !ib->isYUVA()) {
283 SkMatrix combinedMatrix;
284 combinedMatrix.setConcat(localToDevice, srcToDst);
285 if (can_ignore_linear_filtering_subset(src, combinedMatrix, sdc->numSamples())) {
286 restrictToSubset = false;
287 }
288 }
289
290 SkMatrix textureMatrix;
291 if (canUseTextureCoordsAsLocalCoords) {
292 textureMatrix = SkMatrix::I();
293 } else {
294 if (!srcToDst.invert(&textureMatrix)) {
295 return;
296 }
297 }
298 const SkRect* subset = restrictToSubset ? &src : nullptr;
299 const SkRect* domain = coordsAllInsideSrcRect ? &src : nullptr;
300 SkTileMode tileModes[] = {tm, tm};
301 std::unique_ptr<GrFragmentProcessor> fp = skgpu::ganesh::AsFragmentProcessor(
302 rContext, image, sampling, tileModes, textureMatrix, subset, domain);
304 std::move(fp), image->imageInfo().colorInfo(), sdc->colorInfo());
305 if (image->isAlphaOnly()) {
306 if (const auto* shader = as_SB(paint.getShader())) {
307 auto shaderFP = GrFragmentProcessors::Make(shader,
308 GrFPArgs(rContext,
309 &sdc->colorInfo(),
310 sdc->surfaceProps(),
313 if (!shaderFP) {
314 return;
315 }
316 fp = GrBlendFragmentProcessor::Make<SkBlendMode::kDstIn>(std::move(fp),
317 std::move(shaderFP));
318 } else {
319 // Multiply the input (paint) color by the texture (alpha)
321 }
322 }
323
324 GrPaint grPaint;
325 if (!SkPaintToGrPaintReplaceShader(rContext,
326 sdc->colorInfo(),
327 paint,
329 std::move(fp),
330 sdc->surfaceProps(),
331 &grPaint)) {
332 return;
333 }
334
335 if (!mf) {
336 // Can draw the image directly (any mask filter on the paint was converted to an FP already)
337 if (dstClip) {
338 SkPoint srcClipPoints[4];
339 SkPoint* srcClip = nullptr;
340 if (canUseTextureCoordsAsLocalCoords) {
341 // Calculate texture coordinates that match the dst clip
342 GrMapRectPoints(dst, src, dstClip, srcClipPoints, 4);
343 srcClip = srcClipPoints;
344 }
345 sdc->fillQuadWithEdgeAA(clip, std::move(grPaint), aaFlags, localToDevice,
346 dstClip, srcClip);
347 } else {
348 // Provide explicit texture coords when possible, otherwise rely on texture matrix
349 sdc->fillRectWithEdgeAA(clip, std::move(grPaint), aaFlags, localToDevice, dst,
350 canUseTextureCoordsAsLocalCoords ? &src : nullptr);
351 }
352 } else {
353 // Must draw the mask filter as a GrStyledShape. For now, this loses the per-edge AA
354 // information since it always draws with AA, but that should not be noticeable since the
355 // mask filter is probably a blur.
356 GrStyledShape shape;
357 if (dstClip) {
358 // Represent it as an SkPath formed from the dstClip
359 SkPath path;
360 path.addPoly(dstClip, 4, true);
361 shape = GrStyledShape(path);
362 } else {
363 shape = GrStyledShape(dst);
364 }
365
367 rContext, sdc, clip, shape, std::move(grPaint), localToDevice, mf);
368 }
369}
370
372 const SkMatrix& localToDevice,
373 const SkSamplingOptions& origSampling,
374 const SkPaint& paint,
375 SkCanvas::SrcRectConstraint constraint) {
376 SkASSERT(!paint.getMaskFilter() && !paint.getImageFilter());
377 SkASSERT(special->isGaneshBacked());
378
379 SkRect src = SkRect::Make(special->subset());
380 SkRect dst = SkRect::MakeWH(special->width(), special->height());
382
383 SkSamplingOptions sampling = SkSamplingOptions(downgrade_to_filter(origSampling));
384 GrAA aa = fSurfaceDrawContext->chooseAA(paint);
387
389 if (!view) {
390 // This shouldn't happen since we shouldn't be mixing SkSpecialImage subclasses but
391 // returning early should avoid problems in release builds.
392 SkASSERT(false);
393 return;
394 }
395
396 if (constraint == SkCanvas::kFast_SrcRectConstraint) {
397 // If 'fast' was requested, we assume the caller has done sufficient analysis to know the
398 // logical dimensions are safe (which is true for FilterResult, the only current caller that
399 // passes in 'fast'). Without exactify'ing the proxy, GrTextureEffect would re-introduce
400 // subset clamping.
401 view.proxy()->priv().exactify();
402 }
403
405 special->uniqueID(),
406 std::move(view),
407 special->colorInfo());
408 // In most cases this ought to hit draw_texture since there won't be a color filter,
409 // alpha-only texture+shader, or a high filter quality.
410 this->drawEdgeAAImage(&image,
411 src,
412 dst,
413 /* dstClip= */nullptr,
414 aaFlags,
416 sampling,
417 paint,
418 constraint,
419 srcToDst,
421}
422
423void Device::drawImageQuadDirect(const SkImage* image,
424 const SkRect& srcRect,
425 const SkRect& dstRect,
426 const SkPoint dstClip[4],
427 SkCanvas::QuadAAFlags aaFlags,
428 const SkMatrix* preViewMatrix,
429 const SkSamplingOptions& origSampling,
430 const SkPaint& paint,
431 SkCanvas::SrcRectConstraint constraint) {
432 SkRect src;
433 SkRect dst;
434 SkMatrix srcToDst;
436 image->height()),
437 srcRect, dstRect, dstClip,
438 &src, &dst, &srcToDst);
440 return;
441 }
442
443 if (src.contains(image->bounds())) {
445 }
446 // Depending on the nature of image, it can flow through more or less optimal pipelines
449
450 // Get final CTM matrix
451 SkMatrix ctm = this->localToDevice();
452 if (preViewMatrix) {
453 ctm.preConcat(*preViewMatrix);
454 }
455
456 SkSamplingOptions sampling = origSampling;
460 }
461
462 this->drawEdgeAAImage(image,
463 src,
464 dst,
465 dstClip,
466 aaFlags,
467 ctm,
468 sampling,
469 paint,
470 constraint,
471 srcToDst,
472 tileMode);
473}
474
476 const SkPoint dstClips[], const SkMatrix preViewMatrices[],
478 SkCanvas::SrcRectConstraint constraint) {
479 SkASSERT(count > 0);
480 if (!can_use_draw_texture(paint, sampling)) {
481 // Send every entry through drawImageQuad() to handle the more complicated paint
482 int dstClipIndex = 0;
483 for (int i = 0; i < count; ++i) {
484 // Only no clip or quad clip are supported
485 SkASSERT(!set[i].fHasClip || dstClips);
486 SkASSERT(set[i].fMatrixIndex < 0 || preViewMatrices);
487
489 if (set[i].fAlpha != 1.f) {
490 auto paintAlpha = paint.getAlphaf();
491 entryPaint.writable()->setAlphaf(paintAlpha * set[i].fAlpha);
492 }
493 this->drawImageQuadDirect(
494 set[i].fImage.get(), set[i].fSrcRect, set[i].fDstRect,
495 set[i].fHasClip ? dstClips + dstClipIndex : nullptr,
496 static_cast<SkCanvas::QuadAAFlags>(set[i].fAAFlags),
497 set[i].fMatrixIndex < 0 ? nullptr : preViewMatrices + set[i].fMatrixIndex,
498 sampling, *entryPaint, constraint);
499 dstClipIndex += 4 * set[i].fHasClip;
500 }
501 return;
502 }
503
507 SkBlendMode mode = paint.getBlendMode_or(SkBlendMode::kSrcOver);
508
510 // We accumulate compatible proxies until we find an an incompatible one or reach the end and
511 // issue the accumulated 'n' draws starting at 'base'. 'p' represents the number of proxy
512 // switches that occur within the 'n' entries.
513 int base = 0, n = 0, p = 0;
514 auto draw = [&](int nextBase) {
515 if (n > 0) {
516 auto textureXform = GrColorSpaceXform::Make(set[base].fImage->imageInfo().colorInfo(),
517 fSurfaceDrawContext->colorInfo());
518 fSurfaceDrawContext->drawTextureSet(this->clip(),
519 textures.get() + base,
520 n,
521 p,
522 filter,
524 mode,
525 constraint,
526 this->localToDevice(),
527 std::move(textureXform));
528 }
529 base = nextBase;
530 n = 0;
531 p = 0;
532 };
533 int dstClipIndex = 0;
534 for (int i = 0; i < count; ++i) {
535 SkASSERT(!set[i].fHasClip || dstClips);
536 SkASSERT(set[i].fMatrixIndex < 0 || preViewMatrices);
537
538 // Manage the dst clip pointer tracking before any continues are used so we don't lose
539 // our place in the dstClips array.
540 const SkPoint* clip = set[i].fHasClip ? dstClips + dstClipIndex : nullptr;
541 dstClipIndex += 4 * set[i].fHasClip;
542
543 // The default SkDevice implementation is based on drawImageRect which does not allow
544 // non-sorted src rects. TODO: Decide this is OK or make sure we handle it.
545 if (!set[i].fSrcRect.isSorted()) {
546 draw(i + 1);
547 continue;
548 }
549
551 const SkImage_Base* image = as_IB(set[i].fImage.get());
552 // Extract view from image, but skip YUV images so they get processed through
553 // drawImageQuad and the proper effect to dynamically sample their planes.
554 if (!image->isYUVA()) {
555 std::tie(view, std::ignore) =
557 if (image->isAlphaOnly()) {
559 skgpu::Swizzle("aaaa"));
560 view = {view.detachProxy(), view.origin(), swizzle};
561 }
562 }
563
564 if (!view) {
565 // This image can't go through the texture op, send through general image pipeline
566 // after flushing current batch.
567 draw(i + 1);
569 if (set[i].fAlpha != 1.f) {
570 auto paintAlpha = paint.getAlphaf();
571 entryPaint.writable()->setAlphaf(paintAlpha * set[i].fAlpha);
572 }
573 this->drawImageQuadDirect(
574 image, set[i].fSrcRect, set[i].fDstRect, clip,
575 static_cast<SkCanvas::QuadAAFlags>(set[i].fAAFlags),
576 set[i].fMatrixIndex < 0 ? nullptr : preViewMatrices + set[i].fMatrixIndex,
577 sampling, *entryPaint, constraint);
578 continue;
579 }
580
581 textures[i].fProxyView = std::move(view);
582 textures[i].fSrcAlphaType = image->alphaType();
583 textures[i].fSrcRect = set[i].fSrcRect;
584 textures[i].fDstRect = set[i].fDstRect;
585 textures[i].fDstClipQuad = clip;
586 textures[i].fPreViewMatrix =
587 set[i].fMatrixIndex < 0 ? nullptr : preViewMatrices + set[i].fMatrixIndex;
588 textures[i].fColor = texture_color(paint.getColor4f(), set[i].fAlpha,
590 fSurfaceDrawContext->colorInfo());
591 textures[i].fAAFlags = SkToGrQuadAAFlags(set[i].fAAFlags);
592
593 if (n > 0 &&
595 textures[i].fProxyView.proxy(),
596 textures[base].fProxyView.proxy()) ||
597 textures[i].fProxyView.swizzle() != textures[base].fProxyView.swizzle() ||
598 set[i].fImage->alphaType() != set[base].fImage->alphaType() ||
599 !SkColorSpace::Equals(set[i].fImage->colorSpace(), set[base].fImage->colorSpace()))) {
600 draw(i);
601 }
602 // Whether or not we submitted a draw in the above if(), this ith entry is in the current
603 // set being accumulated so increment n, and increment p if proxies are different.
604 ++n;
605 if (n == 1 || textures[i - 1].fProxyView.proxy() != textures[i].fProxyView.proxy()) {
606 // First proxy or a different proxy (that is compatible, otherwise we'd have drawn up
607 // to i - 1).
608 ++p;
609 }
610 }
611 draw(count);
612}
613
614} // namespace skgpu::ganesh
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
static void GrMapRectPoints(const SkRect &inRect, const SkRect &outRect, const SkPoint inPts[], SkPoint outPts[], int ptCount)
Definition: GrRect.h:37
GrQuadAAFlags
Definition: GrTypesPriv.h:247
static GrQuadAAFlags SkToGrQuadAAFlags(unsigned flags)
Definition: GrTypesPriv.h:259
static constexpr bool GrColorTypeIsAlphaOnly(GrColorType ct)
Definition: GrTypesPriv.h:888
GrAA
Definition: GrTypesPriv.h:173
GrColorType
Definition: GrTypesPriv.h:540
static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct)
Definition: GrTypesPriv.h:629
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkBlendMode
Definition: SkBlendMode.h:38
@ kSrcOver
r = s + (1-sa)*d
bool SkPaintToGrPaintReplaceShader(GrRecordingContext *context, const GrColorInfo &dstColorInfo, const SkPaint &skPaint, const SkMatrix &ctm, std::unique_ptr< GrFragmentProcessor > shaderFP, const SkSurfaceProps &surfaceProps, GrPaint *grPaint)
Definition: SkGr.cpp:570
SkColor4f SkColor4fPrepForDst(SkColor4f color, const GrColorInfo &colorInfo)
Definition: SkGr.cpp:283
static SkImage_Base * as_IB(SkImage *image)
Definition: SkImage_Base.h:201
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 SK_Scalar1
Definition: SkScalar.h:18
#define SK_ScalarHalf
Definition: SkScalar.h:19
#define SkScalarRoundToScalar(x)
Definition: SkScalar.h:32
#define SkScalarAbs(x)
Definition: SkScalar.h:39
SkShaderBase * as_SB(SkShader *shader)
Definition: SkShaderBase.h:412
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition: SkTPin.h:19
SkTileMode
Definition: SkTileMode.h:13
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition: aaclip.cpp:27
Definition: GrClip.h:29
GrColorType colorType() const
Definition: GrColorInfo.h:43
SkAlphaType alphaType() const
Definition: GrColorInfo.h:44
static std::unique_ptr< GrFragmentProcessor > Make(std::unique_ptr< GrFragmentProcessor > child, SkColorSpace *src, SkAlphaType srcAT, SkColorSpace *dst, SkAlphaType dstAT)
static sk_sp< GrColorSpaceXform > Make(SkColorSpace *src, SkAlphaType srcAT, SkColorSpace *dst, SkAlphaType dstAT)
static std::unique_ptr< GrFragmentProcessor > MulInputByChildAlpha(std::unique_ptr< GrFragmentProcessor > child)
skgpu::Swizzle swizzle() const
void concatSwizzle(skgpu::Swizzle swizzle)
sk_sp< GrSurfaceProxy > detachProxy()
GrSurfaceOrigin origin() const
GrSurfaceProxy * proxy() const
GrSurfaceProxyPriv priv()
SkRect getBoundsRect() const
bool isFunctionallyExact() const
static constexpr float kLinearInset
static bool ProxiesAreCompatibleAsDynamicState(const GrSurfaceProxy *first, const GrSurfaceProxy *second)
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
@ kNone_QuadAAFlags
Definition: SkCanvas.h:1664
@ kAll_QuadAAFlags
Definition: SkCanvas.h:1665
static bool Equals(const SkColorSpace *, const SkColorSpace *)
const SkMatrix & localToDevice() const
Definition: SkDevice.h:179
bool isAlphaOnly() const
Definition: SkImage.cpp:239
const SkImageInfo & imageInfo() const
Definition: SkImage.h:279
SkAlphaType alphaType() const
Definition: SkImage.cpp:154
int width() const
Definition: SkImage.h:285
SkColorType colorType() const
Definition: SkImage.cpp:152
int height() const
Definition: SkImage.h:291
SkIRect bounds() const
Definition: SkImage.h:303
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
Definition: SkMatrix.h:157
bool invert(SkMatrix *inverse) const
Definition: SkMatrix.h:1206
bool rectStaysRect() const
Definition: SkMatrix.h:271
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
SkMatrix & preConcat(const SkMatrix &other)
Definition: SkMatrix.cpp:674
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition: SkMatrix.cpp:1141
SkMatrix & setConcat(const SkMatrix &a, const SkMatrix &b)
Definition: SkMatrix.cpp:603
Definition: SkPath.h:59
int width() const
int height() const
virtual GrRecordingContext * getContext() const
virtual bool isGaneshBacked() const
uint32_t uniqueID() const
const SkIRect & subset() const
const SkColorInfo & colorInfo() const
T * get() const
Definition: SkRefCnt.h:303
static constexpr Swizzle Concat(const Swizzle &a, const Swizzle &b)
Definition: Swizzle.h:156
static ImageDrawMode OptimizeSampleArea(const SkISize &imageSize, const SkRect &origSrcRect, const SkRect &origDstRect, const SkPoint dstClip[4], SkRect *outSrcRect, SkRect *outDstRect, SkMatrix *outSrcToDst)
static bool CanDisableMipmap(const SkMatrix &viewM, const SkMatrix &localM)
void drawEdgeAAImageSet(const SkCanvas::ImageSetEntry[], int count, const SkPoint dstClips[], const SkMatrix preViewMatrices[], const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
void drawSpecial(SkSpecialImage *, const SkMatrix &localToDevice, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
void drawEdgeAAImage(const SkImage *, const SkRect &src, const SkRect &dst, const SkPoint dstClip[4], SkCanvas::QuadAAFlags, const SkMatrix &localToDevice, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint, const SkMatrix &srcToDst, SkTileMode)
GrRecordingContext * recordingContext() const override
Definition: Device.h:101
const GrColorInfo & colorInfo() const
void fillQuadWithEdgeAA(const GrClip *clip, GrPaint &&paint, GrQuadAAFlags edgeAA, const SkMatrix &viewMatrix, const SkPoint points[4], const SkPoint optionalLocalPoints[4])
void fillRectWithEdgeAA(const GrClip *clip, GrPaint &&paint, GrQuadAAFlags edgeAA, const SkMatrix &viewMatrix, const SkRect &rect, const SkRect *optionalLocalRect=nullptr)
void drawTextureQuad(const GrClip *clip, GrSurfaceProxyView view, GrColorType srcColorType, SkAlphaType srcAlphaType, GrSamplerState::Filter filter, GrSamplerState::MipmapMode mm, SkBlendMode mode, const SkPMColor4f &color, const SkPoint srcQuad[4], const SkPoint dstQuad[4], GrQuadAAFlags edgeAA, const SkRect *subset, const SkMatrix &viewMatrix, sk_sp< GrColorSpaceXform > texXform)
const SkSurfaceProps & surfaceProps() const
void drawTexture(const GrClip *, GrSurfaceProxyView, SkAlphaType, GrSamplerState::Filter, GrSamplerState::MipmapMode, SkBlendMode, const SkPMColor4f &, const SkRect &srcRect, const SkRect &dstRect, GrQuadAAFlags, SkCanvas::SrcRectConstraint, const SkMatrix &, sk_sp< GrColorSpaceXform >)
const Paint & paint
Definition: color_source.cc:38
DlColor color
float SkScalar
Definition: extension.cpp:12
static void draw_texture(const GrCaps *caps, skgpu::ganesh::SurfaceDrawContext *sdc, const GrSurfaceProxyView &src, const SkIRect &srcRect, const SkIRect &drawRect, const SkMatrix &mat, GrSamplerState::WrapMode xTileMode, GrSamplerState::WrapMode yTileMode)
Definition: lazytiling.cpp:155
void DrawShapeWithMaskFilter(GrRecordingContext *rContext, skgpu::ganesh::SurfaceDrawContext *sdc, const GrClip *clip, const GrStyledShape &shape, GrPaint &&paint, const SkMatrix &viewMatrix, const SkMaskFilter *mf)
std::unique_ptr< GrFragmentProcessor > Make(const SkMaskFilter *maskfilter, const GrFPArgs &args, const SkMatrix &ctm)
bool IsSupported(const SkMaskFilter *maskfilter)
PODArray< SkPoint > dstClips
Definition: SkRecords.h:364
sk_sp< const SkImage > image
Definition: SkRecords.h:269
PODArray< SkMatrix > preViewMatrices
Definition: SkRecords.h:365
SkSamplingOptions sampling
Definition: SkRecords.h:337
GrSurfaceProxyView AsView(GrRecordingContext *context, const SkSpecialImage *img)
const uint32_t fp
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 mode
Definition: switches.h:228
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 set
Definition: switches.h:76
dst
Definition: cp.py:12
std::unique_ptr< GrFragmentProcessor > AsFragmentProcessor(GrRecordingContext *rContext, const SkImage *img, SkSamplingOptions sampling, const SkTileMode tileModes[2], const SkMatrix &m, const SkRect *subset, const SkRect *domain)
std::tuple< GrSurfaceProxyView, GrColorType > AsView(GrRecordingContext *rContext, const SkImage *img, skgpu::Mipmapped mipmapped, GrImageTexGenPolicy policy)
SkSamplingOptions(SkFilterMode::kLinear))
Definition: SkRect.h:32
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
const SkColorInfo & colorInfo() const
Definition: SkImageInfo.h:404
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
constexpr float left() const
Definition: SkRect.h:734
void inset(float dx, float dy)
Definition: SkRect.h:1060
constexpr float top() const
Definition: SkRect.h:741
void outset(float dx, float dy)
Definition: SkRect.h:1077
bool contains(SkScalar x, SkScalar y) const
Definition: extension.cpp:19
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
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
const SkFilterMode filter
const SkMipmapMode mipmap