Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Macros | Typedefs | Functions
SkCanvas.cpp File Reference
#include "include/core/SkCanvas.h"
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkBlender.h"
#include "include/core/SkBlurTypes.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkRasterHandleAllocator.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkRegion.h"
#include "include/core/SkShader.h"
#include "include/core/SkStrokeRec.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypes.h"
#include "include/core/SkVertices.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkSafe32.h"
#include "include/private/base/SkTPin.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/base/SkTo.h"
#include "include/private/chromium/Slug.h"
#include "include/utils/SkNoDrawCanvas.h"
#include "src/base/SkEnumBitMask.h"
#include "src/base/SkMSAN.h"
#include "src/core/SkBlenderBase.h"
#include "src/core/SkBlurMaskFilterImpl.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkDevice.h"
#include "src/core/SkImageFilterTypes.h"
#include "src/core/SkImageFilter_Base.h"
#include "src/core/SkImagePriv.h"
#include "src/core/SkLatticeIter.h"
#include "src/core/SkMaskFilterBase.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkPaintPriv.h"
#include "src/core/SkSpecialImage.h"
#include "src/core/SkSurfacePriv.h"
#include "src/core/SkTraceEvent.h"
#include "src/core/SkVerticesPriv.h"
#include "src/effects/colorfilters/SkColorFilterBase.h"
#include "src/image/SkSurface_Base.h"
#include "src/text/GlyphRun.h"
#include "src/utils/SkPatchUtils.h"
#include <algorithm>
#include <memory>
#include <new>
#include <optional>
#include <tuple>
#include <utility>

Go to the source code of this file.

Classes

class  SkCanvas::AutoUpdateQRBounds
 
struct  FilterToSpan
 

Macros

#define RETURN_ON_NULL(ptr)   do { if (nullptr == (ptr)) return; } while (0)
 
#define RETURN_ON_FALSE(pred)   do { if (!(pred)) return; } while (0)
 

Typedefs

using Slug = sktext::gpu::Slug
 

Functions

static skif::ParameterSpace< SkPointcompute_decomposition_center (const SkMatrix &dstToLocal, std::optional< skif::ParameterSpace< SkRect > > contentBounds, const skif::DeviceSpace< SkIRect > &targetOutput)
 
static std::optional< std::pair< skif::Mapping, skif::LayerSpace< SkIRect > > > get_layer_mapping_and_bounds (SkCanvas::FilterSpan filters, const SkMatrix &localToDst, const skif::DeviceSpace< SkIRect > &targetOutput, std::optional< skif::ParameterSpace< SkRect > > contentBounds={}, SkScalar scaleFactor=1.0f)
 
static SkColorType image_filter_color_type (const SkColorInfo &dstInfo)
 
static skif::FilterResult apply_alpha_and_colorfilter (const skif::Context &ctx, const skif::FilterResult &image, const SkPaint &paint)
 
static bool fillable (const SkRect &r)
 
static SkPaint clean_paint_for_lattice (const SkPaint *paint)
 
static const SkBlurMaskFilterImplcan_attempt_blurred_rrect_draw (const SkPaint &paint)
 
static SkPaint clean_paint_for_drawImage (const SkPaint *paint)
 
static SkPaint clean_paint_for_drawVertices (SkPaint paint)
 
static SkSamplingOptions clean_sampling_for_constraint (const SkSamplingOptions &sampling, SkCanvas::SrcRectConstraint constraint)
 
static bool install (SkBitmap *bm, const SkImageInfo &info, const SkRasterHandleAllocator::Rec &rec)
 

Macro Definition Documentation

◆ RETURN_ON_FALSE

#define RETURN_ON_FALSE (   pred)    do { if (!(pred)) return; } while (0)

Definition at line 79 of file SkCanvas.cpp.

◆ RETURN_ON_NULL

#define RETURN_ON_NULL (   ptr)    do { if (nullptr == (ptr)) return; } while (0)

Definition at line 78 of file SkCanvas.cpp.

Typedef Documentation

◆ Slug

Definition at line 85 of file SkCanvas.cpp.

Function Documentation

◆ apply_alpha_and_colorfilter()

static skif::FilterResult apply_alpha_and_colorfilter ( const skif::Context ctx,
const skif::FilterResult image,
const SkPaint paint 
)
static

Definition at line 697 of file SkCanvas.cpp.

699 {
700 // The only effects that apply to layers (other than the SkImageFilter that made this image in
701 // the first place) are transparency and color filters.
703 if (paint.getAlphaf() < 1.f) {
704 result = result.applyColorFilter(ctx, SkColorFilters::Blend(paint.getColor4f(),
705 /*colorSpace=*/nullptr,
707 }
708 if (paint.getColorFilter()) {
709 result = result.applyColorFilter(ctx, paint.refColorFilter());
710 }
711 return result;
712}
@ kDstIn
r = d * sa
static sk_sp< SkColorFilter > Blend(const SkColor4f &c, sk_sp< SkColorSpace >, SkBlendMode mode)
const Paint & paint
sk_sp< SkImage > image
Definition examples.cpp:29
GAsyncResult * result

◆ can_attempt_blurred_rrect_draw()

static const SkBlurMaskFilterImpl * can_attempt_blurred_rrect_draw ( const SkPaint paint)
static

Definition at line 2265 of file SkCanvas.cpp.

2265 {
2266 if (paint.getPathEffect()) {
2267 return nullptr;
2268 }
2269
2270 // TODO: Once stroke-and-fill goes away, we can check the paint's style directly.
2271 if (SkStrokeRec(paint).getStyle() != SkStrokeRec::kFill_Style) {
2272 return nullptr;
2273 }
2274
2275 const SkMaskFilterBase* maskFilter = as_MFB(paint.getMaskFilter());
2276 if (!maskFilter || maskFilter->type() != SkMaskFilterBase::Type::kBlur) {
2277 return nullptr;
2278 }
2279
2280 const SkBlurMaskFilterImpl* blurMaskFilter =
2281 static_cast<const SkBlurMaskFilterImpl*>(maskFilter);
2282 if (blurMaskFilter->blurStyle() != kNormal_SkBlurStyle) {
2283 return nullptr;
2284 }
2285
2286 return blurMaskFilter;
2287}
@ kNormal_SkBlurStyle
fuzzy inside and outside
Definition SkBlurTypes.h:12
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)
SkBlurStyle blurStyle() const
virtual Type type() const =0

◆ clean_paint_for_drawImage()

static SkPaint clean_paint_for_drawImage ( const SkPaint paint)
static

Definition at line 2525 of file SkCanvas.cpp.

2525 {
2526 SkPaint cleaned;
2527 if (paint) {
2528 cleaned = *paint;
2530 cleaned.setPathEffect(nullptr);
2531 }
2532 return cleaned;
2533}
void setStyle(Style style)
Definition SkPaint.cpp:105
@ kFill_Style
set to fill geometry
Definition SkPaint.h:193
void setPathEffect(sk_sp< SkPathEffect > pathEffect)

◆ clean_paint_for_drawVertices()

static SkPaint clean_paint_for_drawVertices ( SkPaint  paint)
static

Definition at line 2537 of file SkCanvas.cpp.

2537 {
2538 paint.setStyle(SkPaint::kFill_Style);
2539 paint.setMaskFilter(nullptr);
2540 paint.setPathEffect(nullptr);
2541 return paint;
2542}

◆ clean_paint_for_lattice()

static SkPaint clean_paint_for_lattice ( const SkPaint paint)
static

Definition at line 2083 of file SkCanvas.cpp.

2083 {
2084 SkPaint cleaned;
2085 if (paint) {
2086 cleaned = *paint;
2087 cleaned.setMaskFilter(nullptr);
2088 cleaned.setAntiAlias(false);
2089 }
2090 return cleaned;
2091}
void setAntiAlias(bool aa)
Definition SkPaint.h:170
void setMaskFilter(sk_sp< SkMaskFilter > maskFilter)

◆ clean_sampling_for_constraint()

static SkSamplingOptions clean_sampling_for_constraint ( const SkSamplingOptions sampling,
SkCanvas::SrcRectConstraint  constraint 
)
static

Definition at line 2612 of file SkCanvas.cpp.

2614 {
2615 if (constraint == SkCanvas::kStrict_SrcRectConstraint) {
2618 }
2619 if (sampling.isAniso()) {
2621 }
2622 }
2623 return sampling;
2624}
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition SkCanvas.h:1542
SkSamplingOptions sampling
Definition SkRecords.h:337
const SkFilterMode filter
const SkMipmapMode mipmap

◆ compute_decomposition_center()

static skif::ParameterSpace< SkPoint > compute_decomposition_center ( const SkMatrix dstToLocal,
std::optional< skif::ParameterSpace< SkRect > >  contentBounds,
const skif::DeviceSpace< SkIRect > &  targetOutput 
)
static

Definition at line 536 of file SkCanvas.cpp.

539 {
540 // Will use the inverse and center of the device bounds if the content bounds aren't provided.
541 SkRect rect = contentBounds ? SkRect(*contentBounds) : SkRect::Make(SkIRect(targetOutput));
542 SkPoint center = {rect.centerX(), rect.centerY()};
543 if (!contentBounds) {
544 // Theoretically, the inverse transform could put center's homogeneous coord behind W = 0,
545 // but that case is handled automatically in Mapping::decomposeCTM later.
546 dstToLocal.mapPoints(&center, 1);
547 }
548
550}
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
static SkScalar center(float pos0, float pos1)
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Definition SkMatrix.cpp:770
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350

◆ fillable()

static bool fillable ( const SkRect r)
static

Definition at line 2077 of file SkCanvas.cpp.

2077 {
2078 SkScalar w = r.width();
2079 SkScalar h = r.height();
2080 return SkIsFinite(w, h) && w > 0 && h > 0;
2081}
static bool SkIsFinite(T x, Pack... values)
float SkScalar
Definition extension.cpp:12
SkScalar w
SkScalar h
constexpr float height() const
Definition SkRect.h:769
constexpr float width() const
Definition SkRect.h:762

◆ get_layer_mapping_and_bounds()

static std::optional< std::pair< skif::Mapping, skif::LayerSpace< SkIRect > > > get_layer_mapping_and_bounds ( SkCanvas::FilterSpan  filters,
const SkMatrix localToDst,
const skif::DeviceSpace< SkIRect > &  targetOutput,
std::optional< skif::ParameterSpace< SkRect > >  contentBounds = {},
SkScalar  scaleFactor = 1.0f 
)
static

Definition at line 572 of file SkCanvas.cpp.

576 {},
577#if defined(SK_RESOLVE_FILTERS_BEFORE_RESTORE)
578 bool mustCoverDst = true,
579#endif
580 SkScalar scaleFactor = 1.0f) {
581 SkMatrix dstToLocal;
582 if (!localToDst.isFinite() ||
583 !localToDst.invert(&dstToLocal)) {
584 return {};
585 }
586
588 compute_decomposition_center(dstToLocal, contentBounds, targetOutput);
589#if defined(SK_RESOLVE_FILTERS_BEFORE_RESTORE)
590 // *after* possibly getting a representative point from the provided content bounds, it might
591 // be necessary to discard the bounds for subsequent layer calculations.
592 if (mustCoverDst) {
593 contentBounds.reset();
594 }
595#endif
596
597 // Determine initial mapping and a reasonable maximum dimension to prevent layer-to-device
598 // transforms with perspective and skew from triggering excessive buffer allocations.
599 skif::Mapping mapping;
601 for (const sk_sp<SkImageFilter>& filter : filters) {
602 if (filter) {
603 capability = std::min(capability, as_IFB(filter)->getCTMCapability());
604 }
605 }
606 if (!mapping.decomposeCTM(localToDst, capability, center)) {
607 return {};
608 }
609 // Push scale factor into layer matrix and device matrix (net no change, but the layer will have
610 // its resolution adjusted in comparison to the final device).
611 if (scaleFactor != 1.0f &&
612 !mapping.adjustLayerSpace(SkMatrix::Scale(scaleFactor, scaleFactor))) {
613 return {};
614 }
615
616 // Perspective and skew could exceed this since mapping.deviceToLayer(targetOutput) is
617 // theoretically unbounded under those conditions. Under a 45 degree rotation, a layer needs to
618 // be 2X larger per side of the prior device in order to fully cover it. We use the max of that
619 // and 2048 for a reasonable upper limit (this allows small layers under extreme transforms to
620 // use more relative resolution than a larger layer).
621 static const int kMinDimThreshold = 2048;
622 int maxLayerDim = std::max(Sk64_pin_to_s32(2 * std::max(SkIRect(targetOutput).width64(),
623 SkIRect(targetOutput).height64())),
624 kMinDimThreshold);
625
626 auto baseLayerBounds = mapping.deviceToLayer(targetOutput);
627 if (contentBounds) {
628 // For better or for worse, user bounds currently act as a hard clip on the layer's
629 // extent (i.e., they implement the CSS filter-effects 'filter region' feature).
630 skif::LayerSpace<SkIRect> knownBounds = mapping.paramToLayer(*contentBounds).roundOut();
631 if (!baseLayerBounds.intersect(knownBounds)) {
632 baseLayerBounds = skif::LayerSpace<SkIRect>::Empty();
633 }
634 }
635
636 skif::LayerSpace<SkIRect> layerBounds;
637 if (!filters.empty()) {
638 layerBounds = skif::LayerSpace<SkIRect>::Union(filters.size(), [&](int i) {
639 return filters[i] ? as_IFB(filters[i])
640 ->getInputBounds(mapping, targetOutput, contentBounds)
641 : baseLayerBounds;
642 });
643 // When a filter is involved, the layer size may be larger than the default maxLayerDim due
644 // to required inputs for filters (e.g. a displacement map with a large radius).
645 if (layerBounds.width() > maxLayerDim || layerBounds.height() > maxLayerDim) {
646 skif::Mapping idealMapping{mapping.layerMatrix()};
647 for (const sk_sp<SkImageFilter>& filter : filters) {
648 if (filter) {
649 auto idealLayerBounds = as_IFB(filter)->getInputBounds(
650 idealMapping, targetOutput, contentBounds);
651 maxLayerDim = std::max(std::max(idealLayerBounds.width(),
652 idealLayerBounds.height()),
653 maxLayerDim);
654 }
655 }
656 }
657 } else {
658 if (baseLayerBounds.isEmpty()) {
659 return {};
660 }
661 layerBounds = baseLayerBounds;
662 }
663
664 if (layerBounds.width() > maxLayerDim || layerBounds.height() > maxLayerDim) {
665 skif::LayerSpace<SkIRect> newLayerBounds(
666 SkIRect::MakeWH(std::min(layerBounds.width(), maxLayerDim),
667 std::min(layerBounds.height(), maxLayerDim)));
669 SkRect::Make(SkIRect(newLayerBounds)),
671 if (!mapping.adjustLayerSpace(adjust)) {
672 return {};
673 } else {
674 layerBounds = newLayerBounds;
675 }
676 }
677
678 return std::make_pair(mapping, layerBounds);
679}
static skif::ParameterSpace< SkPoint > compute_decomposition_center(const SkMatrix &dstToLocal, std::optional< skif::ParameterSpace< SkRect > > contentBounds, const skif::DeviceSpace< SkIRect > &targetOutput)
Definition SkCanvas.cpp:536
static SkImageFilter_Base * as_IFB(SkImageFilter *filter)
static constexpr int32_t Sk64_pin_to_s32(int64_t x)
Definition SkSafe32.h:16
skif::LayerSpace< SkIRect > getInputBounds(const skif::Mapping &mapping, const skif::DeviceSpace< SkIRect > &desiredOutput, std::optional< skif::ParameterSpace< SkRect > > knownContentBounds) const
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition SkMatrix.h:75
@ kFill_ScaleToFit
scales in x and y to fill destination SkRect
Definition SkMatrix.h:137
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
static SkMatrix MakeRectToRect(const SkRect &src, const SkRect &dst, ScaleToFit stf)
Definition SkMatrix.h:1172
bool isFinite() const
Definition SkMatrix.h:1834
constexpr bool empty() const
Definition SkSpan_impl.h:96
constexpr size_t size() const
Definition SkSpan_impl.h:95
const SkMatrix & deviceToLayer() const
bool decomposeCTM(const SkMatrix &ctm, const SkImageFilter *filter, const skif::ParameterSpace< SkPoint > &representativePt)
const SkMatrix & layerMatrix() const
LayerSpace< T > paramToLayer(const ParameterSpace< T > &paramGeometry) const
bool adjustLayerSpace(const SkMatrix &layer)
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition SkRect.h:56
static SkRect Make(const SkISize &size)
Definition SkRect.h:669

◆ image_filter_color_type()

static SkColorType image_filter_color_type ( const SkColorInfo dstInfo)
static

Definition at line 684 of file SkCanvas.cpp.

684 {
685 if (dstInfo.bytesPerPixel() <= 4 &&
686 dstInfo.colorType() != kRGBA_8888_SkColorType &&
687 dstInfo.colorType() != kBGRA_8888_SkColorType) {
688 // "Upgrade" A8, G8, 565, 4444, 1010102, 101010x, and 888x to 8888
689 return kN32_SkColorType;
690 } else {
691 return dstInfo.colorType();
692 }
693}
@ 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
int bytesPerPixel() const
SkColorType colorType() const

◆ install()

static bool install ( SkBitmap bm,
const SkImageInfo info,
const SkRasterHandleAllocator::Rec rec 
)
static

Definition at line 3283 of file SkCanvas.cpp.

3284 {
3285 return bm->installPixels(info, rec.fPixels, rec.fRowBytes, rec.fReleaseProc, rec.fReleaseCtx);
3286}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, void(*releaseProc)(void *addr, void *context), void *context)
Definition SkBitmap.cpp:323
void(* fReleaseProc)(void *pixels, void *ctx)