111 SkDEBUGFAIL(
"Please call real blitter's blitAntiH instead.");
115 SkDEBUGFAIL(
"Please call real blitter's blitV instead.");
119 SkDEBUGFAIL(
"Please call real blitter's blitH instead.");
123 SkDEBUGFAIL(
"Please call real blitter's blitRect instead.");
128 SkDEBUGFAIL(
"Please call real blitter's blitAntiRect instead.");
151 return forceRealBlitter ? fRealBlitter :
this;
173 if (
width > MaskAdditiveBlitter::kMAX_WIDTH) {
178 int64_t storage = rb *
bounds.height();
180 return (
width <= MaskAdditiveBlitter::kMAX_WIDTH) &&
181 (storage <= MaskAdditiveBlitter::kMAX_STORAGE);
195 static const int kMAX_WIDTH = 32;
196 static const int kMAX_STORAGE = 1024;
202 uint32_t fStorage[(kMAX_STORAGE >> 2) + 2];
212 : fRealBlitter(realBlitter)
213 , fMask((uint8_t*)fStorage + 1, ir, ir.
width(),
SkMask::kA8_Format)
230 SK_ABORT(
"Don't use this; directly add alphas to the mask.");
240 uint8_t* row = this->
getRow(y);
253 uint8_t* row = this->
getRow(y);
264 uint8_t* row = this->
getRow(y);
266 memset(row +
x, 0xFF,
width);
333 const size_t kRunsSz = this->
getRunsSz();
379 sectBounds = clipBounds;
381 if (!sectBounds.
intersect(ir, clipBounds)) {
427 for (
int i = 0;
i <
len; ++
i) {
440 if (this->
check(x, 1)) {
497 for (
int i = 0;
i <
len; ++
i) {
538 return SkTo<SkAlpha>(area >> 8);
551 SkFixed area = (
a >> 11) * (
a >> 11) * (
b >> 11);
555 return SkTo<SkAlpha>(area >> 8);
557 return SkTo<SkAlpha>((area >> 8) & 0xFF);
566 return (alpha * fullAlpha) >> 8;
607 SkFixed alpha16 = firstH + (dY >> 1);
608 for (
int i = 1;
i <
R - 1; ++
i) {
609 alphas[
i] = alpha16 >> 8;
634 SkFixed alpha16 = lastH + (dY >> 1);
635 for (
int i =
R - 2;
i > 0;
i--) {
636 alphas[
i] = (alpha16 >> 8) & 0xFF;
650 bool noRealBlitter) {
652 if (fullAlpha == 0xFF && !noRealBlitter) {
658 if (fullAlpha == 0xFF && !noRealBlitter) {
673 bool noRealBlitter) {
678 if (fullAlpha == 0xFF && !noRealBlitter) {
693 bool noRealBlitter) {
695 for (
int i = 0;
i <
len; ++
i) {
699 if (fullAlpha == 0xFF && !noRealBlitter) {
717 bool noRealBlitter) {
727 const int kQuickLen = 31;
728 alignas(2)
char quickMemory[(
sizeof(
SkAlpha) * 2 +
sizeof(int16_t)) * (kQuickLen + 1)];
731 if (
len <= kQuickLen) {
732 alphas = (
SkAlpha*)quickMemory;
738 int16_t* runs = (int16_t*)(alphas + (
len + 1) * 2);
740 for (
int i = 0;
i <
len; ++
i) {
742 alphas[
i] = fullAlpha;
750 SkFixed second = ll - ul - first;
753 alphas[0] = alphas[0] > a1 ? alphas[0] - a1 : 0;
754 alphas[1] = alphas[1] > a2 ? alphas[1] - a2 : 0;
758 for (
int i = uL;
i < lL; ++
i) {
759 if (alphas[
i -
L] > tempAlphas[
i -
L]) {
760 alphas[
i -
L] -= tempAlphas[
i -
L];
771 SkFixed second = lr - ur - first;
774 alphas[
len - 2] = alphas[
len - 2] > a1 ? alphas[
len - 2] - a1 : 0;
775 alphas[
len - 1] = alphas[
len - 1] > a2 ? alphas[
len - 1] - a2 : 0;
779 for (
int i = uR;
i < lR; ++
i) {
780 if (alphas[
i -
L] > tempAlphas[
i -
L]) {
781 alphas[
i -
L] -= tempAlphas[
i -
L];
789 for (
int i = 0;
i <
len; ++
i) {
793 if (fullAlpha == 0xFF && !noRealBlitter) {
801 if (
len > kQuickLen) {
816 bool noRealBlitter) {
829 if (ul == ur && ll == lr) {
846 if (joinLeft <= joinRite) {
858 }
else if (
len == 2) {
860 SkFixed second = ll - ul - first;
887 if (joinLeft < joinRite) {
907 }
else if (
len == 2) {
909 SkFixed second = lr - ur - first;
950 int valuea =
a.fUpperY;
951 int valueb =
b.fUpperY;
953 if (valuea == valueb) {
958 if (valuea == valueb) {
963 return valuea < valueb;
975 *last = list[
count - 1];
1024 if (leftE->
fLowerY + SK_Fixed1 < riteE->fLowerY) {
1032 if (nextCurrE->
fUpperY >= stop_y << 16) {
1069 while (riteE->fLowerY <=
y) {
1070 if (!riteE->update(
y)) {
1093 if (leftE->
fX > riteE->fX || (leftE->
fX == riteE->fX && leftE->
fDX > riteE->fDX)) {
1107 if (0 == (dLeft | dRite)) {
1116 if (fullTop > fullBot) {
1121 if (fullRite >= fullLeft) {
1122 if (partialTop > 0) {
1123 if (partialLeft > 0) {
1129 fullLeft, fullTop - 1, fullRite - fullLeft,
fixed_to_alpha(partialTop));
1130 if (partialRite > 0) {
1139 if (fullBot > fullTop &&
1146 fullRite - fullLeft,
1152 if (partialBot > 0) {
1153 if (partialLeft > 0) {
1159 fullLeft, fullBot, fullRite - fullLeft,
fixed_to_alpha(partialBot));
1160 if (partialRite > 0) {
1173 if (partialTop > 0) {
1180 if (fullBot > fullTop) {
1184 if (partialBot > 0) {
1193 y = local_bot_fixed;
1199 const SkFixed kSnapHalf = kSnapDigit >> 1;
1200 const SkFixed kSnapMask = (-1 ^ (kSnapDigit - 1));
1209 SkAlpha* maskRow = isUsingMask
1218 if ((
int)(
y & 0xFFFF0000) !=
y) {
1224 SkASSERT((
left & kSnapMask) >= leftBound && (rite & kSnapMask) <= riteBound &&
1225 (nextLeft & kSnapMask) >= leftBound &&
1226 (nextRite & kSnapMask) <= riteBound);
1231 nextLeft & kSnapMask,
1232 nextRite & kSnapMask,
1250 SkASSERT((
left & kSnapMask) >= leftBound && (rite & kSnapMask) <= riteBound &&
1251 (nextLeft & kSnapMask) >= leftBound &&
1252 (nextRite & kSnapMask) <= riteBound);
1257 nextLeft & kSnapMask,
1258 nextRite & kSnapMask,
1282 SkASSERT((
left & kSnapMask) >= leftBound && (rite & kSnapMask) <= riteBound &&
1283 (nextLeft & kSnapMask) >= leftBound && (nextRite & kSnapMask) <= riteBound);
1288 nextLeft & kSnapMask,
1289 nextRite & kSnapMask,
1298 y = local_bot_fixed;
1305 leftE->
fY = riteE->fY =
y;
1312 *nextNextY =
y > nextY &&
y < *nextNextY ?
y : *nextNextY;
1333 if (
prev->fX <= newEdge->
fX) {
1337 newEdge = newEdge->
fNext;
1348 if (
start->fNext == newEdge) {
1352 if (after->
fX >= newEdge->
fX) {
1419 bool skipIntersect) {
1420 prevHead->
fX = prevHead->
fUpperX = leftClip;
1421 nextTail->
fX = nextTail->
fUpperX = rightClip;
1457 bool in_interval = isInverse;
1492 bool noRealBlitter = forceRLE;
1499 bool prev_in_interval = in_interval;
1500 in_interval = !(
w & windingMask) == isInverse;
1502 bool isLeft = in_interval && !prev_in_interval;
1503 bool isRite = !in_interval && prev_in_interval;
1507 currE->
goY(nextY, yShift);
1522 noRealBlitter || (fullAlpha == 0xFF &&
1529 leftDY = currE->
fDY;
1532 currE->
goY(nextY, yShift);
1538 while (currE->
fLowerY <= nextY) {
1557 if (currE->
fLowerY <= nextY) {
1569 if (!skipIntersect) {
1590 noRealBlitter || (fullAlpha == 0xFF &&
1613 bool pathContainedInClip,
1624 if (
path.isInverseFillType()) {
1631 if (
rect.fTop < start_y) {
1632 rect.fTop = start_y;
1634 if (
rect.fBottom > stop_y) {
1635 rect.fBottom = stop_y;
1637 if (!
rect.isEmpty()) {
1649 headEdge.
fPrev =
nullptr;
1650 headEdge.
fNext = edge;
1656 edge->
fPrev = &headEdge;
1658 tailEdge.
fPrev = last;
1659 tailEdge.
fNext =
nullptr;
1665 last->
fNext = &tailEdge;
1669 if (!pathContainedInClip && start_y <
clipRect.fTop) {
1672 if (!pathContainedInClip && stop_y >
clipRect.fBottom) {
1682 path.getBounds().roundOut(&ir);
1687 if (!
path.isInverseFillType() &&
path.isConvex() &&
count >= 2) {
1689 &headEdge, blitter, start_y, stop_y, leftBound, rightBound, isUsingMask);
1693 bool skipIntersect =
path.countPoints() > (stop_y - start_y) * 2;
1721 if (
bounds.width() < 3) {
1733 bool containedInClip = clipBounds.
contains(ir);
1734 bool isInverse =
path.isInverseFillType();
1757 }
else if (!isInverse &&
path.isConvex()) {
static float next(float f)
static float prev(float f)
static constexpr T SkAlign4(T x)
#define SkDEBUGFAIL(message)
#define SK_ABORT(message,...)
#define SkFixedCeilToInt(x)
static SkFixed SkFixedCeilToFixed(SkFixed x)
#define SkFixedFloorToInt(x)
#define SkFixedRoundToInt(x)
static SkFixed SkFixedFloorToFixed(SkFixed x)
static SkFixed SkFixedMul(SkFixed a, SkFixed b)
static constexpr int32_t SkLeftShift(int32_t value, int32_t shift)
static constexpr int32_t SK_MinS32
static constexpr int32_t SK_MaxS32
static bool SkPathFillType_IsInverse(SkPathFillType ft)
static bool SkPathFillType_IsEvenOdd(SkPathFillType ft)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
void swap(sk_sp< T > &a, sk_sp< T > &b)
static int32_t SkAbs32(int32_t value)
static void remove_edge(EdgeType *edge)
void backward_insert_edge_based_on_x(EdgeType *edge)
static void insert_edge_after(EdgeType *edge, EdgeType *afterMe)
EdgeType * backward_insert_start(EdgeType *prev, SkFixed x)
static void validate_sort(const SkAnalyticEdge *edge)
static void update_next_next_y(SkFixed y, SkFixed nextY, SkFixed *nextNextY)
static void check_intersection(const SkAnalyticEdge *edge, SkFixed nextY, SkFixed *nextNextY)
static SkFixed approximate_intersection(SkFixed l1, SkFixed r1, SkFixed l2, SkFixed r2)
static SkAlpha trapezoid_to_alpha(SkFixed l1, SkFixed l2)
static SkAlpha partial_triangle_to_alpha(SkFixed a, SkFixed b)
static void blit_two_alphas(AdditiveBlitter *blitter, int y, int x, SkAlpha a1, SkAlpha a2, SkAlpha fullAlpha, SkAlpha *maskRow, bool noRealBlitter)
static void validate_edges_for_y(const SkAnalyticEdge *edge, SkFixed y)
static void blit_aaa_trapezoid_row(AdditiveBlitter *blitter, int y, SkFixed ul, SkFixed ur, SkFixed ll, SkFixed lr, SkFixed lDY, SkFixed rDY, SkAlpha fullAlpha, SkAlpha *maskRow, bool noRealBlitter)
static void check_intersection_fwd(const SkAnalyticEdge *edge, SkFixed nextY, SkFixed *nextNextY)
static void blit_single_alpha(AdditiveBlitter *blitter, int y, int x, SkAlpha alpha, SkAlpha fullAlpha, SkAlpha *maskRow, bool noRealBlitter)
static bool operator<(const SkAnalyticEdge &a, const SkAnalyticEdge &b)
static void blit_full_alpha(AdditiveBlitter *blitter, int y, int x, int len, SkAlpha fullAlpha, SkAlpha *maskRow, bool noRealBlitter)
static void add_alpha(SkAlpha *alpha, SkAlpha delta)
static SkAlpha fixed_to_alpha(SkFixed f)
static bool is_smooth_enough(SkAnalyticEdge *thisEdge, SkAnalyticEdge *nextEdge, int stop_y)
static void aaa_walk_edges(SkAnalyticEdge *prevHead, SkAnalyticEdge *nextTail, SkPathFillType fillType, AdditiveBlitter *blitter, int start_y, int stop_y, SkFixed leftClip, SkFixed rightClip, bool isUsingMask, bool forceRLE, bool skipIntersect)
static bool try_blit_fat_anti_rect(SkBlitter *blitter, const SkPath &path, const SkIRect &clip)
static void aaa_walk_convex_edges(SkAnalyticEdge *prevHead, AdditiveBlitter *blitter, int start_y, int stop_y, SkFixed leftBound, SkFixed riteBound, bool isUsingMask)
static void safely_add_alpha(SkAlpha *alpha, SkAlpha delta)
static void aaa_fill_path(const SkPath &path, const SkIRect &clipRect, AdditiveBlitter *blitter, int start_y, int stop_y, bool pathContainedInClip, bool isUsingMask, bool forceRLE)
static void compute_alpha_below_line(SkAlpha *alphas, SkFixed l, SkFixed r, SkFixed dY, SkAlpha fullAlpha)
static void insert_new_edges(SkAnalyticEdge *newEdge, SkFixed y, SkFixed *nextNextY)
static bool edges_too_close(SkAnalyticEdge *prev, SkAnalyticEdge *next, SkFixed lowerY)
static void compute_alpha_above_line(SkAlpha *alphas, SkFixed l, SkFixed r, SkFixed dY, SkAlpha fullAlpha)
static SkAlpha get_partial_alpha(SkAlpha alpha, SkFixed partialHeight)
static void blit_trapezoid_row(AdditiveBlitter *blitter, int y, SkFixed ul, SkFixed ur, SkFixed ll, SkFixed lr, SkFixed lDY, SkFixed rDY, SkAlpha fullAlpha, SkAlpha *maskRow, bool noRealBlitter)
static SkAnalyticEdge * sort_edges(SkAnalyticEdge *list[], int count, SkAnalyticEdge **last)
void SkTQSort(T *begin, T *end, const C &lessThan)
constexpr uint8_t SkToU8(S x)
void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override
virtual void blitAntiH(int x, int y, const SkAlpha alpha)=0
virtual void flush_if_y_changed(SkFixed y, SkFixed nextY)=0
virtual void blitAntiH(int x, int y, const SkAlpha antialias[], int len)=0
void blitH(int x, int y, int width) override
Blit a horizontal run of one or more pixels.
~AdditiveBlitter() override
void blitRect(int x, int y, int width, int height) override
Blit a solid rectangle one or more pixels wide.
virtual SkBlitter * getRealBlitter(bool forceRealBlitter=false)=0
virtual void blitAntiH(int x, int y, int width, const SkAlpha alpha)=0
void blitV(int x, int y, int height, SkAlpha alpha) override
Blit a vertical run of pixels with a constant alpha value.
void blitAntiRect(int x, int y, int width, int height, SkAlpha leftAlpha, SkAlpha rightAlpha) override
static bool CanHandleRect(const SkIRect &bounds)
void blitRect(int x, int y, int width, int height) override
Blit a solid rectangle one or more pixels wide.
void blitAntiRect(int x, int y, int width, int height, SkAlpha leftAlpha, SkAlpha rightAlpha) override
~MaskAdditiveBlitter() override
void flush_if_y_changed(SkFixed y, SkFixed nextY) override
void blitV(int x, int y, int height, SkAlpha alpha) override
Blit a vertical run of pixels with a constant alpha value.
void blitAntiH(int x, int y, const SkAlpha antialias[], int len) override
SkBlitter * getRealBlitter(bool forceRealBlitter) override
MaskAdditiveBlitter(SkBlitter *realBlitter, const SkIRect &ir, const SkIRect &clipBounds, bool isInverse)
SkAlpha snapAlpha(SkAlpha alpha)
void flush_if_y_changed(SkFixed y, SkFixed nextY) override
RunBasedAdditiveBlitter(SkBlitter *realBlitter, const SkIRect &ir, const SkIRect &clipBounds, bool isInverse)
SkBlitter * getRealBlitter(bool forceRealBlitter) override
bool check(int x, int width) const
void blitAntiH(int x, int y, const SkAlpha antialias[], int len) override
~RunBasedAdditiveBlitter() override
SafeRLEAdditiveBlitter(SkBlitter *realBlitter, const SkIRect &ir, const SkIRect &clipBounds, bool isInverse)
void blitAntiH(int x, int y, const SkAlpha antialias[], int len) override
void reset(int width)
Reinitialize for a new scanline.
SK_ALWAYS_INLINE int add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue, int offsetX)
static SkAlpha CatchOverflow(int alpha)
void blitFatAntiRect(const SkRect &rect)
virtual void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1)
virtual int requestRowsPreserved() const
virtual void blitMask(const SkMask &, const SkIRect &clip)
virtual void blitAntiRect(int x, int y, int width, int height, SkAlpha leftAlpha, SkAlpha rightAlpha)
virtual void * allocBlitMemory(size_t sz)
virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])=0
virtual void blitH(int x, int y, int width)=0
Blit a horizontal run of one or more pixels.
virtual void blitV(int x, int y, int height, SkAlpha alpha)
Blit a vertical run of pixels with a constant alpha value.
virtual void blitRect(int x, int y, int width, int height)
Blit a solid rectangle one or more pixels wide.
static float max(float r, float g, float b)
static float min(float r, float g, float b)
Optional< SkRect > bounds
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
sk_sp< SkBlender > blender SkRect rect
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
bool updateCubic(bool sortY=true)
static const int kDefaultAccuracy
bool update(SkFixed last_y, bool sortY=true)
bool intersect(const SkIRect &r)
int32_t fBottom
larger y-axis bounds
constexpr int32_t top() const
constexpr int32_t height() const
constexpr int32_t right() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
int32_t fLeft
smaller x-axis bounds
constexpr int32_t left() const
bool contains(int32_t x, int32_t y) const
int32_t fRight
larger x-axis bounds
static SkRect Make(const SkISize &size)