Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | Protected Attributes | List of all members
SkBlitter Class Referenceabstract

#include <SkBlitter.h>

Inheritance diagram for SkBlitter:
AdditiveBlitter FakeBlitter InverseBlitter SkA8_Blitter SkA8_Coverage_Blitter SkAAClip::Builder::Blitter SkAAClipBlitter SkNullBlitter SkRasterBlitter SkRasterPipelineBlitter SkRectClipBlitter SkRgnBuilder SkRgnClipBlitter SkSpriteBlitter TestBlitter

Public Member Functions

virtual ~SkBlitter ()
 
virtual void blitH (int x, int y, int width)=0
 Blit a horizontal run of one or more pixels. More...
 
virtual void blitAntiH (int x, int y, const SkAlpha antialias[], const int16_t runs[])=0
 
virtual void blitV (int x, int y, int height, SkAlpha alpha)
 Blit a vertical run of pixels with a constant alpha value. More...
 
virtual void blitRect (int x, int y, int width, int height)
 Blit a solid rectangle one or more pixels wide. More...
 
virtual void blitAntiRect (int x, int y, int width, int height, SkAlpha leftAlpha, SkAlpha rightAlpha)
 
void blitFatAntiRect (const SkRect &rect)
 
virtual void blitMask (const SkMask &, const SkIRect &clip)
 
virtual void blitAntiH2 (int x, int y, U8CPU a0, U8CPU a1)
 
virtual void blitAntiV2 (int x, int y, U8CPU a0, U8CPU a1)
 
virtual bool isNullBlitter () const
 
virtual int requestRowsPreserved () const
 
virtual void * allocBlitMemory (size_t sz)
 
non-virtual helpers
void blitRectRegion (const SkIRect &rect, const SkRegion &clip)
 
void blitRegion (const SkRegion &clip)
 

Static Public Member Functions

static bool UseLegacyBlitter (const SkPixmap &, const SkPaint &, const SkMatrix &)
 
Factories

Return the correct blitter to use given the specified context.

static SkBlitterChoose (const SkPixmap &dst, const SkMatrix &ctm, const SkPaint &paint, SkArenaAlloc *, bool drawCoverage, sk_sp< SkShader > clipShader, const SkSurfaceProps &props)
 
static SkBlitterChooseSprite (const SkPixmap &dst, const SkPaint &, const SkPixmap &src, int left, int top, SkArenaAlloc *, sk_sp< SkShader > clipShader)
 

Protected Attributes

SkAutoMalloc fBlitMemory
 

Detailed Description

SkBlitter and its subclasses are responsible for actually writing pixels into memory. Besides efficiency, they handle clipping and antialiasing. A SkBlitter subclass contains all the context needed to generate pixels for the destination and how src/generated pixels map to the destination. The coordinates passed to the blitX calls are in destination pixel space.

Definition at line 38 of file SkBlitter.h.

Constructor & Destructor Documentation

◆ ~SkBlitter()

SkBlitter::~SkBlitter ( )
virtual

Definition at line 46 of file SkBlitter.cpp.

46{}

Member Function Documentation

◆ allocBlitMemory()

virtual void * SkBlitter::allocBlitMemory ( size_t  sz)
inlinevirtual

This function allocates memory for the blitter that the blitter then owns. The memory can be used by the calling function at will, but it will be released when the blitter's destructor is called. This function returns nullptr if no persistent memory is needed by the blitter.

Reimplemented in SkRectClipBlitter, and SkRgnClipBlitter.

Definition at line 130 of file SkBlitter.h.

130 {
132 }
void * reset(size_t size=0, OnShrink shrink=kAlloc_OnShrink)
Definition: SkAutoMalloc.h:53
SkAutoMalloc fBlitMemory
Definition: SkBlitter.h:163

◆ blitAntiH()

virtual void SkBlitter::blitAntiH ( int  x,
int  y,
const SkAlpha  antialias[],
const int16_t  runs[] 
)
pure virtual

Blit a horizontal run of antialiased pixels; runs[] is a sparse zero-terminated run-length encoding of spans of constant alpha values. The runs[] and antialias[] work together to represent long runs of pixels with the same alphas. The runs[] contains the number of pixels with the same alpha, and antialias[] contain the coverage value for that number of pixels. The runs[] (and antialias[]) are encoded in a clever way. The runs array is zero terminated, and has enough entries for each pixel plus one, in most cases some of the entries will not contain valid data. An entry in the runs array contains the number of pixels (np) that have the same alpha value. The next np value is found np entries away. For example, if runs[0] = 7, then the next valid entry will by at runs[7]. The runs array and antialias[] are coupled by index. So, if the np entry is at runs[45] = 12 then the alpha value can be found at antialias[45] = 0x88. This would mean to use an alpha value of 0x88 for the next 12 pixels starting at pixel 45.

Implemented in SkAAClip::Builder::Blitter, SkA8_Blitter, SkA8_Coverage_Blitter, SkARGB32_Blitter, SkARGB32_Black_Blitter, SkRgnBuilder, AdditiveBlitter, SkSpriteBlitter, TestBlitter, FakeBlitter, SkAAClipBlitter, SkNullBlitter, SkRectClipBlitter, SkRgnClipBlitter, SkARGB32_Shader_Blitter, SkRasterPipelineBlitter, and InverseBlitter.

◆ blitAntiH2()

virtual void SkBlitter::blitAntiH2 ( int  x,
int  y,
U8CPU  a0,
U8CPU  a1 
)
inlinevirtual

Reimplemented in SkARGB32_Blitter, SkARGB32_Opaque_Blitter, SkARGB32_Black_Blitter, and SkRasterPipelineBlitter.

Definition at line 81 of file SkBlitter.h.

81 {
82 int16_t runs[3];
83 uint8_t aa[2];
84
85 runs[0] = 1;
86 runs[1] = 1;
87 runs[2] = 0;
88 aa[0] = SkToU8(a0);
89 aa[1] = SkToU8(a1);
90 this->blitAntiH(x, y, aa, runs);
91 }
constexpr uint8_t SkToU8(S x)
Definition: SkTo.h:22
virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])=0
double y
double x

◆ blitAntiRect()

void SkBlitter::blitAntiRect ( int  x,
int  y,
int  width,
int  height,
SkAlpha  leftAlpha,
SkAlpha  rightAlpha 
)
virtual

Blit a rectangle with one alpha-blended column on the left, width (zero or more) opaque pixels, and one alpha-blended column on the right. The result will always be at least two pixels wide.

Default implementation doesn't check for easy optimizations such as alpha == 255; also uses blitV(), which some subclasses may not support.

Reimplemented in SkAAClip::Builder::Blitter, SkRectClipBlitter, SkRgnClipBlitter, AdditiveBlitter, and MaskAdditiveBlitter.

Definition at line 143 of file SkBlitter.cpp.

144 {
145 if (leftAlpha > 0) { // we may send in x = -1 with leftAlpha = 0
146 this->blitV(x, y, height, leftAlpha);
147 }
148 x++;
149 if (width > 0) {
150 this->blitRect(x, y, width, height);
151 x += width;
152 }
153 if (rightAlpha > 0) {
154 this->blitV(x, y, height, rightAlpha);
155 }
156}
virtual void blitV(int x, int y, int height, SkAlpha alpha)
Blit a vertical run of pixels with a constant alpha value.
Definition: SkBlitter.cpp:119
virtual void blitRect(int x, int y, int width, int height)
Blit a solid rectangle one or more pixels wide.
Definition: SkBlitter.cpp:133
int32_t height
int32_t width

◆ blitAntiV2()

virtual void SkBlitter::blitAntiV2 ( int  x,
int  y,
U8CPU  a0,
U8CPU  a1 
)
inlinevirtual

Reimplemented in SkARGB32_Blitter, SkARGB32_Opaque_Blitter, SkARGB32_Black_Blitter, and SkRasterPipelineBlitter.

Definition at line 94 of file SkBlitter.h.

94 {
95 int16_t runs[2];
96 uint8_t aa[1];
97
98 runs[0] = 1;
99 runs[1] = 0;
100 aa[0] = SkToU8(a0);
101 this->blitAntiH(x, y, aa, runs);
102 // reset in case the clipping blitter modified runs
103 runs[0] = 1;
104 runs[1] = 0;
105 aa[0] = SkToU8(a1);
106 this->blitAntiH(x, y + 1, aa, runs);
107 }

◆ blitFatAntiRect()

void SkBlitter::blitFatAntiRect ( const SkRect rect)

Definition at line 67 of file SkBlitter.cpp.

67 {
68 SkIRect bounds = rect.roundOut();
69 SkASSERT(bounds.width() >= 3);
70
71 // skbug.com/7813
72 // To ensure consistency of the threaded backend (a rect that's considered fat in the init-once
73 // phase must also be considered fat in the draw phase), we have to deal with rects with small
74 // heights because the horizontal tiling in the threaded backend may change the height.
75 //
76 // This also implies that we cannot do vertical tiling unless we can blit any rect (not just the
77 // fat one.)
78 if (bounds.height() == 0) {
79 return;
80 }
81
82 int runSize = bounds.width() + 1; // +1 so we can set runs[bounds.width()] = 0
83 void* storage = this->allocBlitMemory(runSize * (sizeof(int16_t) + sizeof(SkAlpha)));
84 int16_t* runs = reinterpret_cast<int16_t*>(storage);
85 SkAlpha* alphas = reinterpret_cast<SkAlpha*>(runs + runSize);
86
87 runs[0] = 1;
88 runs[1] = bounds.width() - 2;
89 runs[bounds.width() - 1] = 1;
90 runs[bounds.width()] = 0;
91
92 SkScalar partialL = bounds.fLeft + 1 - rect.fLeft;
93 SkScalar partialR = rect.fRight - (bounds.fRight - 1);
94 SkScalar partialT = bounds.fTop + 1 - rect.fTop;
95 SkScalar partialB = rect.fBottom - (bounds.fBottom - 1);
96
97 if (bounds.height() == 1) {
98 partialT = rect.fBottom - rect.fTop;
99 }
100
101 alphas[0] = ScalarToAlpha(partialL * partialT);
102 alphas[1] = ScalarToAlpha(partialT);
103 alphas[bounds.width() - 1] = ScalarToAlpha(partialR * partialT);
104 this->blitAntiH(bounds.fLeft, bounds.fTop, alphas, runs);
105
106 if (bounds.height() > 2) {
107 this->blitAntiRect(bounds.fLeft, bounds.fTop + 1, bounds.width() - 2, bounds.height() - 2,
108 ScalarToAlpha(partialL), ScalarToAlpha(partialR));
109 }
110
111 if (bounds.height() > 1) {
112 alphas[0] = ScalarToAlpha(partialL * partialB);
113 alphas[1] = ScalarToAlpha(partialB);
114 alphas[bounds.width() - 1] = ScalarToAlpha(partialR * partialB);
115 this->blitAntiH(bounds.fLeft, bounds.fBottom - 1, alphas, runs);
116 }
117}
#define SkASSERT(cond)
Definition: SkAssert.h:116
static SkAlpha ScalarToAlpha(SkScalar a)
Definition: SkBlitter.cpp:62
uint8_t SkAlpha
Definition: SkColor.h:26
virtual void blitAntiRect(int x, int y, int width, int height, SkAlpha leftAlpha, SkAlpha rightAlpha)
Definition: SkBlitter.cpp:143
virtual void * allocBlitMemory(size_t sz)
Definition: SkBlitter.h:130
float SkScalar
Definition: extension.cpp:12
Optional< SkRect > bounds
Definition: SkRecords.h:189
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
Definition: SkRect.h:32
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33

◆ blitH()

virtual void SkBlitter::blitH ( int  x,
int  y,
int  width 
)
pure virtual

◆ blitMask()

void SkBlitter::blitMask ( const SkMask mask,
const SkIRect clip 
)
virtual

Blit a pattern of pixels defined by a rectangle-clipped mask; typically used for text.

Reimplemented in SkA8_Blitter, SkA8_Coverage_Blitter, SkARGB32_Blitter, SkARGB32_Opaque_Blitter, SkARGB32_Shader_Blitter, SkAAClip::Builder::Blitter, SkAAClipBlitter, SkNullBlitter, SkRectClipBlitter, SkRgnClipBlitter, SkRasterPipelineBlitter, InverseBlitter, and SkSpriteBlitter.

Definition at line 201 of file SkBlitter.cpp.

201 {
203
204 if (mask.fFormat == SkMask::kLCD16_Format) {
205 return; // needs to be handled by subclass
206 }
207
208 if (mask.fFormat == SkMask::kBW_Format) {
209 int cx = clip.fLeft;
210 int cy = clip.fTop;
211 int maskLeft = mask.fBounds.fLeft;
212 int maskRowBytes = mask.fRowBytes;
213 int height = clip.height();
214
215 const uint8_t* bits = mask.getAddr1(cx, cy);
216
217 SkDEBUGCODE(const uint8_t* endOfImage =
218 mask.fImage + (mask.fBounds.height() - 1) * maskRowBytes
219 + ((mask.fBounds.width() + 7) >> 3));
220
221 if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) {
222 while (--height >= 0) {
223 int affectedRightBit = mask.fBounds.width() - 1;
224 ptrdiff_t rowBytes = (affectedRightBit >> 3) + 1;
225 SkASSERT(bits + rowBytes <= endOfImage);
226 U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1);
227 bits_to_runs(this, cx, cy, bits, 0xFF, rowBytes, rightMask);
228 bits += maskRowBytes;
229 cy += 1;
230 }
231 } else {
232 // Bits is calculated as the offset into the mask at the point {cx, cy} therefore, all
233 // addressing into the bit mask is relative to that point. Since this is an address
234 // calculated from a arbitrary bit in that byte, calculate the left most bit.
235 int bitsLeft = cx - ((cx - maskLeft) & 7);
236
237 // Everything is relative to the bitsLeft.
238 int leftEdge = cx - bitsLeft;
239 SkASSERT(leftEdge >= 0);
240 int rightEdge = clip.fRight - bitsLeft;
241 SkASSERT(rightEdge > leftEdge);
242
243 // Calculate left byte and mask
244 const uint8_t* leftByte = bits;
245 U8CPU leftMask = 0xFFU >> (leftEdge & 7);
246
247 // Calculate right byte and mask
248 int affectedRightBit = rightEdge - 1;
249 const uint8_t* rightByte = bits + (affectedRightBit >> 3);
250 U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1);
251
252 // leftByte and rightByte are byte locations therefore, to get a count of bytes the
253 // code must add one.
254 ptrdiff_t rowBytes = rightByte - leftByte + 1;
255
256 while (--height >= 0) {
257 SkASSERT(bits + rowBytes <= endOfImage);
258 bits_to_runs(this, bitsLeft, cy, bits, leftMask, rowBytes, rightMask);
259 bits += maskRowBytes;
260 cy += 1;
261 }
262 }
263 } else {
264 int width = clip.width();
265 AutoSTMalloc<64, int16_t> runStorage(width + 1);
266 int16_t* runs = runStorage.get();
267 const uint8_t* aa = mask.getAddr8(clip.fLeft, clip.fTop);
268
269 SkOpts::memset16((uint16_t*)runs, 1, width);
270 runs[width] = 0;
271
272 int height = clip.height();
273 int y = clip.fTop;
274 while (--height >= 0) {
275 this->blitAntiH(clip.fLeft, y, aa, runs);
276 aa += mask.fRowBytes;
277 y += 1;
278 }
279 }
280}
static void bits_to_runs(SkBlitter *blitter, int x, int y, const uint8_t bits[], uint8_t left_mask, ptrdiff_t rowBytes, uint8_t right_mask)
Definition: SkBlitter.cpp:160
static uint8_t generate_right_mask(int maskBitCount)
Definition: SkBlitter.cpp:197
unsigned U8CPU
Definition: SkCPUTypes.h:18
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
void(* memset16)(uint16_t[], uint16_t, int)
constexpr int32_t height() const
Definition: SkRect.h:165
constexpr int32_t width() const
Definition: SkRect.h:158
bool contains(int32_t x, int32_t y) const
Definition: SkRect.h:463
int32_t fRight
larger x-axis bounds
Definition: SkRect.h:35
const uint32_t fRowBytes
Definition: SkMask.h:43
@ kLCD16_Format
565 alpha for r/g/b
Definition: SkMask.h:31
@ kBW_Format
1bit per pixel mask (e.g. monochrome)
Definition: SkMask.h:27
const uint8_t * getAddr8(int x, int y) const
Definition: SkMask.h:79
const uint8_t * getAddr1(int x, int y) const
Definition: SkMask.h:68
uint8_t const *const fImage
Definition: SkMask.h:41
const SkIRect fBounds
Definition: SkMask.h:42
const Format fFormat
Definition: SkMask.h:44

◆ blitRect()

void SkBlitter::blitRect ( int  x,
int  y,
int  width,
int  height 
)
virtual

Blit a solid rectangle one or more pixels wide.

Reimplemented in SkAAClip::Builder::Blitter, SkAAClipBlitter, SkNullBlitter, SkRectClipBlitter, SkRgnClipBlitter, SkA8_Blitter, SkA8_Coverage_Blitter, SkSpriteBlitter_Memcpy, SkRasterPipelineSpriteBlitter, SkARGB32_Blitter, SkARGB32_Shader_Blitter, SkRasterPipelineBlitter, AdditiveBlitter, MaskAdditiveBlitter, InverseBlitter, Sprite_D32_S32, and SkSpriteBlitter.

Definition at line 133 of file SkBlitter.cpp.

133 {
134 SkASSERT(width > 0);
135 while (--height >= 0) {
136 this->blitH(x, y++, width);
137 }
138}
virtual void blitH(int x, int y, int width)=0
Blit a horizontal run of one or more pixels.

◆ blitRectRegion()

void SkBlitter::blitRectRegion ( const SkIRect rect,
const SkRegion clip 
)

Definition at line 300 of file SkBlitter.cpp.

300 {
302
303 while (!clipper.done()) {
304 const SkIRect& cr = clipper.rect();
305 this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
306 clipper.next();
307 }
308}
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34

◆ blitRegion()

void SkBlitter::blitRegion ( const SkRegion clip)

Definition at line 310 of file SkBlitter.cpp.

310 {
311 SkRegionPriv::VisitSpans(clip, [this](const SkIRect& r) {
312 this->blitRect(r.left(), r.top(), r.width(), r.height());
313 });
314}
static void VisitSpans(const SkRegion &rgn, const std::function< void(const SkIRect &)> &)
Definition: SkRegion.cpp:1555
constexpr int32_t top() const
Definition: SkRect.h:120
constexpr int32_t left() const
Definition: SkRect.h:113

◆ blitV()

void SkBlitter::blitV ( int  x,
int  y,
int  height,
SkAlpha  alpha 
)
virtual

Blit a vertical run of pixels with a constant alpha value.

Reimplemented in SkAAClip::Builder::Blitter, SkAAClipBlitter, SkNullBlitter, SkRectClipBlitter, SkRgnClipBlitter, SkA8_Blitter, SkA8_Coverage_Blitter, SkARGB32_Blitter, SkARGB32_Shader_Blitter, SkRasterPipelineBlitter, AdditiveBlitter, MaskAdditiveBlitter, InverseBlitter, and SkSpriteBlitter.

Definition at line 119 of file SkBlitter.cpp.

119 {
120 if (alpha == 255) {
121 this->blitRect(x, y, 1, height);
122 } else {
123 int16_t runs[2];
124 runs[0] = 1;
125 runs[1] = 0;
126
127 while (--height >= 0) {
128 this->blitAntiH(x, y++, &alpha, runs);
129 }
130 }
131}

◆ Choose()

SkBlitter * SkBlitter::Choose ( const SkPixmap dst,
const SkMatrix ctm,
const SkPaint paint,
SkArenaAlloc alloc,
bool  drawCoverage,
sk_sp< SkShader clipShader,
const SkSurfaceProps props 
)
static

Definition at line 685 of file SkBlitter.cpp.

691 {
692 SkASSERT(alloc);
693
694 if (kUnknown_SkColorType == device.colorType()) {
695 return alloc->make<SkNullBlitter>();
696 }
697
698 // We may tweak the original paint as we go.
700
701 if (auto mode = paint->asBlendMode()) {
702 // We have the most fast-paths for SrcOver, so see if we can act like SrcOver.
703 if (mode.value() != SkBlendMode::kSrcOver) {
704 switch (CheckFastPath(*paint, SkColorTypeIsAlwaysOpaque(device.colorType()))) {
706 paint.writable()->setBlendMode(SkBlendMode::kSrcOver);
707 break;
709 return alloc->make<SkNullBlitter>();
710 default:
711 break;
712 }
713 }
714
715 // A Clear blend mode will ignore the entire color pipeline, as if Src mode with 0x00000000.
716 if (mode.value() == SkBlendMode::kClear) {
717 SkPaint* p = paint.writable();
718 p->setShader(nullptr);
719 p->setColorFilter(nullptr);
720 p->setBlendMode(SkBlendMode::kSrc);
721 p->setColor(0x00000000);
722 }
723 }
724
725 if (paint->getColorFilter()) {
726 SkPaintPriv::RemoveColorFilter(paint.writable(), device.colorSpace());
727 }
728 SkASSERT(!paint->getColorFilter());
729
730 if (drawCoverage) {
731 if (device.colorType() == kAlpha_8_SkColorType) {
732 SkASSERT(!paint->getShader());
733 SkASSERT(paint->isSrcOver());
734 return alloc->make<SkA8_Coverage_Blitter>(device, *paint);
735 }
736 return alloc->make<SkNullBlitter>();
737 }
738
739 if (paint->isDither() && !SkPaintPriv::ShouldDither(*paint, device.colorType())) {
740 paint.writable()->setDither(false);
741 }
742
743 auto CreateSkRPBlitter = [&]() -> SkBlitter* {
744 auto blitter = SkCreateRasterPipelineBlitter(device, *paint, ctm, alloc, clipShader, props);
745 return blitter ? blitter
746 : alloc->make<SkNullBlitter>();
747 };
748
749 // We'll end here for many interesting cases: color spaces, color filters, most color types.
750 if (clipShader || !UseLegacyBlitter(device, *paint, ctm)) {
751 return CreateSkRPBlitter();
752 }
753
754 // Everything but legacy kN32_SkColorType should already be handled.
755 SkASSERT(device.colorType() == kN32_SkColorType);
756
757 // And we should be blending with SrcOver
758 SkASSERT(paint->asBlendMode() == SkBlendMode::kSrcOver);
759
760 // Legacy blitters keep their shader state on a shader context.
761 SkShaderBase::Context* shaderContext = nullptr;
762 if (paint->getShader()) {
763 shaderContext = as_SB(paint->getShader())
764 ->makeContext({paint->getAlpha(),
766 device.colorType(),
767 device.colorSpace(),
768 props},
769 alloc);
770
771 // Creating the context isn't always possible... try fallbacks before giving up.
772 if (!shaderContext) {
773 return CreateSkRPBlitter();
774 }
775 }
776
777 if (shaderContext) {
778 return alloc->make<SkARGB32_Shader_Blitter>(device, *paint, shaderContext);
779 } else if (paint->getColor() == SK_ColorBLACK) {
780 return alloc->make<SkARGB32_Black_Blitter>(device, *paint);
781 } else if (paint->getAlpha() == 0xFF) {
782 return alloc->make<SkARGB32_Opaque_Blitter>(device, *paint);
783 } else {
784 return alloc->make<SkARGB32_Blitter>(device, *paint);
785 }
786}
SkBlendFastPath CheckFastPath(const SkPaint &paint, bool dstIsOpaque)
@ kSrcOver
r = s + (1-sa)*d
@ kClear
r = 0
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition: SkColorType.h:21
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
SkBlitter * SkCreateRasterPipelineBlitter(const SkPixmap &, const SkPaint &, const SkMatrix &ctm, SkArenaAlloc *, sk_sp< SkShader > clipShader, const SkSurfaceProps &props)
SK_API bool SkColorTypeIsAlwaysOpaque(SkColorType ct)
Definition: SkImageInfo.cpp:48
SkShaderBase * as_SB(SkShader *shader)
Definition: SkShaderBase.h:412
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
Definition: SkArenaAlloc.h:120
static bool UseLegacyBlitter(const SkPixmap &, const SkPaint &, const SkMatrix &)
Definition: SkBlitter.cpp:648
static void RemoveColorFilter(SkPaint *, SkColorSpace *dstCS)
static bool ShouldDither(const SkPaint &, SkColorType)
Context * makeContext(const ContextRec &, SkArenaAlloc *) const
const Paint & paint
Definition: color_source.cc:38
VkDevice device
Definition: main.cc:53
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

◆ ChooseSprite()

SkBlitter * SkBlitter::ChooseSprite ( const SkPixmap dst,
const SkPaint paint,
const SkPixmap src,
int  left,
int  top,
SkArenaAlloc alloc,
sk_sp< SkShader clipShader 
)
static

Definition at line 195 of file SkBlitter_Sprite.cpp.

197 {
198 /* We currently ignore antialiasing and filtertype, meaning we will take our
199 special blitters regardless of these settings. Ignoring filtertype seems fine
200 since by definition there is no scale in the matrix. Ignoring antialiasing is
201 a bit of a hack, since we "could" pass in the fractional left/top for the bitmap,
202 and respect that by blending the edges of the bitmap against the device. To support
203 this we could either add more special blitters here, or detect antialiasing in the
204 paint and return null if it is set, forcing the client to take the slow shader case
205 (which does respect soft edges).
206 */
207 SkASSERT(alloc != nullptr);
208
209 // TODO: in principle SkRasterPipelineSpriteBlitter could be made to handle this.
211 return nullptr;
212 }
213
214 SkSpriteBlitter* blitter = nullptr;
215
217 // Do not use any of these optimized memory blitters
218 } else if (0 == SkColorSpaceXformSteps(source,dst).flags.mask() && !clipShader) {
220 blitter = alloc->make<SkSpriteBlitter_Memcpy>(source);
221 }
222 if (!blitter) {
223 switch (dst.colorType()) {
224 case kN32_SkColorType:
225 blitter = SkSpriteBlitter::ChooseL32(source, paint, alloc);
226 break;
227 default:
228 break;
229 }
230 }
231 }
232 if (!blitter && !paint.getMaskFilter()) {
233 blitter = alloc->make<SkRasterPipelineSpriteBlitter>(source, alloc, clipShader);
234 }
235
236 if (blitter && blitter->setup(dst, left,top, paint)) {
237 return blitter;
238 }
239
240 return nullptr;
241}
kUnpremul_SkAlphaType
bool gSkForceRasterPipelineBlitter
Definition: SkBlitter.cpp:44
static bool left(const SkPoint &p0, const SkPoint &p1)
SkAlphaType alphaType() const
Definition: SkBitmap.h:162
static bool Supports(const SkPixmap &dst, const SkPixmap &src, const SkPaint &paint)
static SkSpriteBlitter * ChooseL32(const SkPixmap &source, const SkPaint &, SkArenaAlloc *)
virtual bool setup(const SkPixmap &dst, int left, int top, const SkPaint &)
SkBitmap source
Definition: examples.cpp:28
FlutterSemanticsFlag flags
dst
Definition: cp.py:12

◆ isNullBlitter()

bool SkBlitter::isNullBlitter ( ) const
virtual

Special method just to identify the null blitter, which is returned from Choose() if the request cannot be fulfilled. Default impl returns false.

Reimplemented in SkNullBlitter.

Definition at line 48 of file SkBlitter.cpp.

48{ return false; }

◆ requestRowsPreserved()

virtual int SkBlitter::requestRowsPreserved ( ) const
inlinevirtual

Special methods for blitters that can blit more than one row at a time. This function returns the number of rows that this blitter could optimally process at a time. It is still required to support blitting one scanline at a time.

Reimplemented in SkRectClipBlitter, and SkRgnClipBlitter.

Definition at line 122 of file SkBlitter.h.

122{ return 1; }

◆ UseLegacyBlitter()

bool SkBlitter::UseLegacyBlitter ( const SkPixmap device,
const SkPaint paint,
const SkMatrix matrix 
)
static

Definition at line 648 of file SkBlitter.cpp.

650 {
652 return false;
653 }
654#if defined(SK_FORCE_RASTER_PIPELINE_BLITTER)
655 return false;
656#else
657
658 if (paint.isDither()) {
659 return false;
660 }
661
662 const SkMaskFilterBase* mf = as_MFB(paint.getMaskFilter());
663
664 // The legacy blitters cannot handle any of these "complex" features (anymore).
665 if (device.alphaType() == kUnpremul_SkAlphaType ||
666 !paint.isSrcOver() ||
667 (mf && mf->getFormat() == SkMask::k3D_Format)) {
668 return false;
669 }
670
671 auto cs = device.colorSpace();
672 // We check (indirectly via makeContext()) later on if the shader can handle the colorspace
673 // in legacy mode, so here we just focus on if a single color needs raster-pipeline.
674 if (cs && !paint.getShader()) {
675 if (!paint.getColor4f().fitsInBytes() || !cs->isSRGB()) {
676 return false;
677 }
678 }
679
680 // Only kN32 is handled by legacy blitters now
681 return device.colorType() == kN32_SkColorType;
682#endif
683}
bool gSkForceRasterPipelineBlitter
Definition: SkBlitter.cpp:44
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)
virtual SkMask::Format getFormat() const =0
@ k3D_Format
3 8bit per pixl planes: alpha, mul, add
Definition: SkMask.h:29

Member Data Documentation

◆ fBlitMemory

SkAutoMalloc SkBlitter::fBlitMemory
protected

Definition at line 163 of file SkBlitter.h.


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