From a6ddde9097fbef2940c6a4f785dae15978ef2533 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 14 Feb 2019 16:59:52 +0100 Subject: Port several Skia upstream fixes. --- gfx/skia/skia/include/core/SkPath.h | 2 +- gfx/skia/skia/include/core/SkPathRef.h | 2 ++ gfx/skia/skia/src/core/SkPath.cpp | 23 ++++++++++--- gfx/skia/skia/src/core/SkPathPriv.h | 5 +++ gfx/skia/skia/src/core/SkScan_Path.cpp | 61 +++++++++++++++++----------------- 5 files changed, 58 insertions(+), 35 deletions(-) (limited to 'gfx/skia') diff --git a/gfx/skia/skia/include/core/SkPath.h b/gfx/skia/skia/include/core/SkPath.h index d1af4f31b..bde07c498 100644 --- a/gfx/skia/skia/include/core/SkPath.h +++ b/gfx/skia/skia/include/core/SkPath.h @@ -373,7 +373,7 @@ public: @param extraPtCount The number of extra points the path should preallocate for. */ - void incReserve(unsigned extraPtCount); + void incReserve(int extraPtCount); /** Set the beginning of the next contour to the point (x,y). diff --git a/gfx/skia/skia/include/core/SkPathRef.h b/gfx/skia/skia/include/core/SkPathRef.h index 0c5cc1aed..d497e7e08 100644 --- a/gfx/skia/skia/include/core/SkPathRef.h +++ b/gfx/skia/skia/include/core/SkPathRef.h @@ -547,6 +547,8 @@ private: friend class PathRefTest_Private; friend class ForceIsRRect_Private; // unit test isRRect + friend class SkPath; + friend class SkPathPriv; }; #endif diff --git a/gfx/skia/skia/src/core/SkPath.cpp b/gfx/skia/skia/src/core/SkPath.cpp index 8f93c9c18..db160d9b7 100644 --- a/gfx/skia/skia/src/core/SkPath.cpp +++ b/gfx/skia/skia/src/core/SkPath.cpp @@ -716,9 +716,11 @@ void SkPath::setConvexity(Convexity c) { fFirstDirection = SkPathPriv::kUnknown_FirstDirection; \ } while (0) -void SkPath::incReserve(U16CPU inc) { +void SkPath::incReserve(int inc) { SkDEBUGCODE(this->validate();) - SkPathRef::Editor(&fPathRef, inc, inc); + if (inc > 0) { + SkPathRef::Editor(&fPathRef, inc, inc); + } SkDEBUGCODE(this->validate();) } @@ -1691,6 +1693,13 @@ static void subdivide_cubic_to(SkPath* path, const SkPoint pts[4], } void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const { + if (matrix.isIdentity()) { + if (dst != nullptr && dst != this) { + *dst = *this; + } + return; + } + SkDEBUGCODE(this->validate();) if (dst == nullptr) { dst = (SkPath*)this; @@ -1738,13 +1747,20 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const { matrix.mapPoints(ed.points(), ed.pathRef()->countPoints()); dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection; } else { + Convexity convexity = Convexity(fConvexity); + SkPathRef::CreateTransformedCopy(&dst->fPathRef, *fPathRef.get(), matrix); if (this != dst) { dst->fFillType = fFillType; - dst->fConvexity = fConvexity; dst->fIsVolatile = fIsVolatile; } + + if (matrix.isScaleTranslate() && SkPathPriv::IsAxisAligned(*this)) { + dst->fConvexity = convexity; + } else { + dst->fConvexity = kUnknown_Convexity; + } if (SkPathPriv::kUnknown_FirstDirection == fFirstDirection) { dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection; @@ -1758,7 +1774,6 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const { } else if (det2x2 > 0) { dst->fFirstDirection = fFirstDirection.load(); } else { - dst->fConvexity = kUnknown_Convexity; dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection; } } diff --git a/gfx/skia/skia/src/core/SkPathPriv.h b/gfx/skia/skia/src/core/SkPathPriv.h index 029cb759d..cfcdc4cac 100644 --- a/gfx/skia/skia/src/core/SkPathPriv.h +++ b/gfx/skia/skia/src/core/SkPathPriv.h @@ -121,6 +121,11 @@ public: static const SkScalar* ConicWeightData(const SkPath& path) { return path.fPathRef->conicWeights(); } + + static bool IsAxisAligned(const SkPath& path) { + SkRect tmp; + return (path.fPathRef->fIsRRect | path.fPathRef->fIsOval) || path.isRect(&tmp); + } }; #endif diff --git a/gfx/skia/skia/src/core/SkScan_Path.cpp b/gfx/skia/skia/src/core/SkScan_Path.cpp index d15d2d54b..5e00e3abe 100644 --- a/gfx/skia/skia/src/core/SkScan_Path.cpp +++ b/gfx/skia/skia/src/core/SkScan_Path.cpp @@ -241,9 +241,17 @@ static bool update_edge(SkEdge* edge, int last_y) { return false; } -static void walk_convex_edges(SkEdge* prevHead, SkPath::FillType, - SkBlitter* blitter, int start_y, int stop_y, - PrePostProc proc) { +// Unexpected conditions for which we need to return +#define ASSERT_RETURN(cond) \ + do { \ + if (!(cond)) { \ + SkASSERT(false); \ + return; \ + } \ + } while (0) + +// Needs Y to only change once (looser than convex in X) +static void walk_simple_edges(SkEdge* prevHead, SkBlitter* blitter, int start_y, int stop_y) { validate_sort(prevHead->fNext); SkEdge* leftE = prevHead->fNext; @@ -258,30 +266,28 @@ static void walk_convex_edges(SkEdge* prevHead, SkPath::FillType, // not lining up, so we take the max. int local_top = SkMax32(leftE->fFirstY, riteE->fFirstY); #endif - SkASSERT(local_top >= start_y); + ASSERT_RETURN(local_top >= start_y); - for (;;) { + while (local_top < stop_y) { SkASSERT(leftE->fFirstY <= stop_y); SkASSERT(riteE->fFirstY <= stop_y); - if (leftE->fX > riteE->fX || (leftE->fX == riteE->fX && - leftE->fDX > riteE->fDX)) { - SkTSwap(leftE, riteE); - } - int local_bot = SkMin32(leftE->fLastY, riteE->fLastY); local_bot = SkMin32(local_bot, stop_y - 1); - SkASSERT(local_top <= local_bot); + ASSERT_RETURN(local_top <= local_bot); SkFixed left = leftE->fX; SkFixed dLeft = leftE->fDX; SkFixed rite = riteE->fX; SkFixed dRite = riteE->fDX; int count = local_bot - local_top; - SkASSERT(count >= 0); + ASSERT_RETURN(count >= 0); if (0 == (dLeft | dRite)) { int L = SkFixedRoundToInt(left); int R = SkFixedRoundToInt(rite); + if (L > R) { + SkTSwap(L, R); + } if (L < R) { count += 1; blitter->blitRect(L, local_top, R - L, count); @@ -291,6 +297,9 @@ static void walk_convex_edges(SkEdge* prevHead, SkPath::FillType, do { int L = SkFixedRoundToInt(left); int R = SkFixedRoundToInt(rite); + if (L > R) { + SkTSwap(L, R); + } if (L < R) { blitter->blitH(L, local_top, R - L); } @@ -303,28 +312,21 @@ static void walk_convex_edges(SkEdge* prevHead, SkPath::FillType, leftE->fX = left; riteE->fX = rite; - if (update_edge(leftE, local_bot)) { + if (!update_edge(leftE, local_bot)) { if (currE->fFirstY >= stop_y) { - break; + return; // we're done } leftE = currE; currE = currE->fNext; + ASSERT_RETURN(leftE->fFirstY == local_top); } - if (update_edge(riteE, local_bot)) { + if (!update_edge(riteE, local_bot)) { if (currE->fFirstY >= stop_y) { - break; + return; // we're done } riteE = currE; currE = currE->fNext; - } - - SkASSERT(leftE); - SkASSERT(riteE); - - // check our bottom clip - SkASSERT(local_top == local_bot + 1); - if (local_top >= stop_y) { - break; + ASSERT_RETURN(riteE->fFirstY == local_top); } } } @@ -500,9 +502,9 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte proc = PrePostInverseBlitterProc; } - if (path.isConvex() && (nullptr == proc)) { - SkASSERT(count >= 2); // convex walker does not handle missing right edges - walk_convex_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, nullptr); + // count >= 2 is required as the convex walker does not handle missing right edges + if (path.isConvex() && (nullptr == proc) && count >= 2) { + walk_simple_edges(&headEdge, blitter, start_y, stop_y); } else { int rightEdge; if (clipRect) { @@ -766,8 +768,7 @@ static void sk_fill_triangle(const SkPoint pts[], const SkIRect* clipRect, if (clipRect && start_y < clipRect->fTop) { start_y = clipRect->fTop; } - walk_convex_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, start_y, stop_y, nullptr); -// walk_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, start_y, stop_y, nullptr); + walk_simple_edges(&headEdge, blitter, start_y, stop_y); } void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip, -- cgit v1.2.3 From c13bd1bba28a71d0a2263882b3c72d59a8c32478 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 17 Feb 2019 14:54:12 +0100 Subject: Revert "Port several Skia upstream fixes." This reverts commit 260b06c1c96285459947231a93f08e413be89dd0. This fixes #976 --- gfx/skia/skia/include/core/SkPath.h | 2 +- gfx/skia/skia/include/core/SkPathRef.h | 2 -- gfx/skia/skia/src/core/SkPath.cpp | 23 +++---------- gfx/skia/skia/src/core/SkPathPriv.h | 5 --- gfx/skia/skia/src/core/SkScan_Path.cpp | 61 +++++++++++++++++----------------- 5 files changed, 35 insertions(+), 58 deletions(-) (limited to 'gfx/skia') diff --git a/gfx/skia/skia/include/core/SkPath.h b/gfx/skia/skia/include/core/SkPath.h index bde07c498..d1af4f31b 100644 --- a/gfx/skia/skia/include/core/SkPath.h +++ b/gfx/skia/skia/include/core/SkPath.h @@ -373,7 +373,7 @@ public: @param extraPtCount The number of extra points the path should preallocate for. */ - void incReserve(int extraPtCount); + void incReserve(unsigned extraPtCount); /** Set the beginning of the next contour to the point (x,y). diff --git a/gfx/skia/skia/include/core/SkPathRef.h b/gfx/skia/skia/include/core/SkPathRef.h index d497e7e08..0c5cc1aed 100644 --- a/gfx/skia/skia/include/core/SkPathRef.h +++ b/gfx/skia/skia/include/core/SkPathRef.h @@ -547,8 +547,6 @@ private: friend class PathRefTest_Private; friend class ForceIsRRect_Private; // unit test isRRect - friend class SkPath; - friend class SkPathPriv; }; #endif diff --git a/gfx/skia/skia/src/core/SkPath.cpp b/gfx/skia/skia/src/core/SkPath.cpp index db160d9b7..8f93c9c18 100644 --- a/gfx/skia/skia/src/core/SkPath.cpp +++ b/gfx/skia/skia/src/core/SkPath.cpp @@ -716,11 +716,9 @@ void SkPath::setConvexity(Convexity c) { fFirstDirection = SkPathPriv::kUnknown_FirstDirection; \ } while (0) -void SkPath::incReserve(int inc) { +void SkPath::incReserve(U16CPU inc) { SkDEBUGCODE(this->validate();) - if (inc > 0) { - SkPathRef::Editor(&fPathRef, inc, inc); - } + SkPathRef::Editor(&fPathRef, inc, inc); SkDEBUGCODE(this->validate();) } @@ -1693,13 +1691,6 @@ static void subdivide_cubic_to(SkPath* path, const SkPoint pts[4], } void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const { - if (matrix.isIdentity()) { - if (dst != nullptr && dst != this) { - *dst = *this; - } - return; - } - SkDEBUGCODE(this->validate();) if (dst == nullptr) { dst = (SkPath*)this; @@ -1747,20 +1738,13 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const { matrix.mapPoints(ed.points(), ed.pathRef()->countPoints()); dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection; } else { - Convexity convexity = Convexity(fConvexity); - SkPathRef::CreateTransformedCopy(&dst->fPathRef, *fPathRef.get(), matrix); if (this != dst) { dst->fFillType = fFillType; + dst->fConvexity = fConvexity; dst->fIsVolatile = fIsVolatile; } - - if (matrix.isScaleTranslate() && SkPathPriv::IsAxisAligned(*this)) { - dst->fConvexity = convexity; - } else { - dst->fConvexity = kUnknown_Convexity; - } if (SkPathPriv::kUnknown_FirstDirection == fFirstDirection) { dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection; @@ -1774,6 +1758,7 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const { } else if (det2x2 > 0) { dst->fFirstDirection = fFirstDirection.load(); } else { + dst->fConvexity = kUnknown_Convexity; dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection; } } diff --git a/gfx/skia/skia/src/core/SkPathPriv.h b/gfx/skia/skia/src/core/SkPathPriv.h index cfcdc4cac..029cb759d 100644 --- a/gfx/skia/skia/src/core/SkPathPriv.h +++ b/gfx/skia/skia/src/core/SkPathPriv.h @@ -121,11 +121,6 @@ public: static const SkScalar* ConicWeightData(const SkPath& path) { return path.fPathRef->conicWeights(); } - - static bool IsAxisAligned(const SkPath& path) { - SkRect tmp; - return (path.fPathRef->fIsRRect | path.fPathRef->fIsOval) || path.isRect(&tmp); - } }; #endif diff --git a/gfx/skia/skia/src/core/SkScan_Path.cpp b/gfx/skia/skia/src/core/SkScan_Path.cpp index 5e00e3abe..d15d2d54b 100644 --- a/gfx/skia/skia/src/core/SkScan_Path.cpp +++ b/gfx/skia/skia/src/core/SkScan_Path.cpp @@ -241,17 +241,9 @@ static bool update_edge(SkEdge* edge, int last_y) { return false; } -// Unexpected conditions for which we need to return -#define ASSERT_RETURN(cond) \ - do { \ - if (!(cond)) { \ - SkASSERT(false); \ - return; \ - } \ - } while (0) - -// Needs Y to only change once (looser than convex in X) -static void walk_simple_edges(SkEdge* prevHead, SkBlitter* blitter, int start_y, int stop_y) { +static void walk_convex_edges(SkEdge* prevHead, SkPath::FillType, + SkBlitter* blitter, int start_y, int stop_y, + PrePostProc proc) { validate_sort(prevHead->fNext); SkEdge* leftE = prevHead->fNext; @@ -266,28 +258,30 @@ static void walk_simple_edges(SkEdge* prevHead, SkBlitter* blitter, int start_y, // not lining up, so we take the max. int local_top = SkMax32(leftE->fFirstY, riteE->fFirstY); #endif - ASSERT_RETURN(local_top >= start_y); + SkASSERT(local_top >= start_y); - while (local_top < stop_y) { + for (;;) { SkASSERT(leftE->fFirstY <= stop_y); SkASSERT(riteE->fFirstY <= stop_y); + if (leftE->fX > riteE->fX || (leftE->fX == riteE->fX && + leftE->fDX > riteE->fDX)) { + SkTSwap(leftE, riteE); + } + int local_bot = SkMin32(leftE->fLastY, riteE->fLastY); local_bot = SkMin32(local_bot, stop_y - 1); - ASSERT_RETURN(local_top <= local_bot); + SkASSERT(local_top <= local_bot); SkFixed left = leftE->fX; SkFixed dLeft = leftE->fDX; SkFixed rite = riteE->fX; SkFixed dRite = riteE->fDX; int count = local_bot - local_top; - ASSERT_RETURN(count >= 0); + SkASSERT(count >= 0); if (0 == (dLeft | dRite)) { int L = SkFixedRoundToInt(left); int R = SkFixedRoundToInt(rite); - if (L > R) { - SkTSwap(L, R); - } if (L < R) { count += 1; blitter->blitRect(L, local_top, R - L, count); @@ -297,9 +291,6 @@ static void walk_simple_edges(SkEdge* prevHead, SkBlitter* blitter, int start_y, do { int L = SkFixedRoundToInt(left); int R = SkFixedRoundToInt(rite); - if (L > R) { - SkTSwap(L, R); - } if (L < R) { blitter->blitH(L, local_top, R - L); } @@ -312,21 +303,28 @@ static void walk_simple_edges(SkEdge* prevHead, SkBlitter* blitter, int start_y, leftE->fX = left; riteE->fX = rite; - if (!update_edge(leftE, local_bot)) { + if (update_edge(leftE, local_bot)) { if (currE->fFirstY >= stop_y) { - return; // we're done + break; } leftE = currE; currE = currE->fNext; - ASSERT_RETURN(leftE->fFirstY == local_top); } - if (!update_edge(riteE, local_bot)) { + if (update_edge(riteE, local_bot)) { if (currE->fFirstY >= stop_y) { - return; // we're done + break; } riteE = currE; currE = currE->fNext; - ASSERT_RETURN(riteE->fFirstY == local_top); + } + + SkASSERT(leftE); + SkASSERT(riteE); + + // check our bottom clip + SkASSERT(local_top == local_bot + 1); + if (local_top >= stop_y) { + break; } } } @@ -502,9 +500,9 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte proc = PrePostInverseBlitterProc; } - // count >= 2 is required as the convex walker does not handle missing right edges - if (path.isConvex() && (nullptr == proc) && count >= 2) { - walk_simple_edges(&headEdge, blitter, start_y, stop_y); + if (path.isConvex() && (nullptr == proc)) { + SkASSERT(count >= 2); // convex walker does not handle missing right edges + walk_convex_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, nullptr); } else { int rightEdge; if (clipRect) { @@ -768,7 +766,8 @@ static void sk_fill_triangle(const SkPoint pts[], const SkIRect* clipRect, if (clipRect && start_y < clipRect->fTop) { start_y = clipRect->fTop; } - walk_simple_edges(&headEdge, blitter, start_y, stop_y); + walk_convex_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, start_y, stop_y, nullptr); +// walk_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, start_y, stop_y, nullptr); } void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip, -- cgit v1.2.3 From 91903016bd260ffdb10d374900741ede33df2020 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 17 Feb 2019 21:31:54 +0100 Subject: Skia: Be consistent about int for incReserve. Upstream port. --- gfx/skia/skia/include/core/SkPath.h | 2 +- gfx/skia/skia/src/core/SkPath.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'gfx/skia') diff --git a/gfx/skia/skia/include/core/SkPath.h b/gfx/skia/skia/include/core/SkPath.h index d1af4f31b..bde07c498 100644 --- a/gfx/skia/skia/include/core/SkPath.h +++ b/gfx/skia/skia/include/core/SkPath.h @@ -373,7 +373,7 @@ public: @param extraPtCount The number of extra points the path should preallocate for. */ - void incReserve(unsigned extraPtCount); + void incReserve(int extraPtCount); /** Set the beginning of the next contour to the point (x,y). diff --git a/gfx/skia/skia/src/core/SkPath.cpp b/gfx/skia/skia/src/core/SkPath.cpp index 8f93c9c18..b7d392025 100644 --- a/gfx/skia/skia/src/core/SkPath.cpp +++ b/gfx/skia/skia/src/core/SkPath.cpp @@ -716,9 +716,11 @@ void SkPath::setConvexity(Convexity c) { fFirstDirection = SkPathPriv::kUnknown_FirstDirection; \ } while (0) -void SkPath::incReserve(U16CPU inc) { +void SkPath::incReserve(int inc) { SkDEBUGCODE(this->validate();) - SkPathRef::Editor(&fPathRef, inc, inc); + if (inc > 0) { + SkPathRef::Editor(&fPathRef, inc, inc); + } SkDEBUGCODE(this->validate();) } -- cgit v1.2.3 From ca3861669b4507ab9295370ee14d4f1d6b87e0c2 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 17 Feb 2019 22:11:40 +0100 Subject: Skia: Validate allocation size in GrBufferAllocPool using SkSafeMath. Upstream port of commit 7469a9341afab19271b8ef07af5c16a0f2c4ccc1 --- gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'gfx/skia') diff --git a/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp b/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp index 993e1c59d..c6097b03b 100644 --- a/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp +++ b/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp @@ -152,13 +152,18 @@ void* GrBufferAllocPool::makeSpace(size_t size, BufferBlock& back = fBlocks.back(); size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree; size_t pad = GrSizeAlignUpPad(usedBytes, alignment); - if ((size + pad) <= back.fBytesFree) { + SkSafeMath safeMath; + size_t alignedSize = safeMath.add(pad, size); + if (!safeMath.ok()) { + return nullptr; + } + if (alignedSize <= back.fBytesFree) { memset((void*)(reinterpret_cast(fBufferPtr) + usedBytes), 0, pad); usedBytes += pad; *offset = usedBytes; *buffer = back.fBuffer; - back.fBytesFree -= size + pad; - fBytesInUse += size + pad; + back.fBytesFree -= alignedSize; + fBytesInUse += alignedSize; VALIDATE(); return (void*)(reinterpret_cast(fBufferPtr) + usedBytes); } -- cgit v1.2.3 From 27f45bc243b45a13c65fb42db0369fd8b8317675 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Mon, 18 Feb 2019 11:49:00 +0100 Subject: Don't trust convexity when applying transforms. In theory, a convex shape transformed by an affine matrix should still be convex. However, due to numerical imprecision of floats, when we try to determine if something is convex, we can get different answers pre and post a transformation (think of two line segments nearly co-linear). Convex paths take a faster scan converter, but it is only well behaved if the path is, in fact, convex. Thus we have to be conservative about which paths we mark as convex, and cant's trust transformed paths to retain their convexity. We re-calculate when a transform is applied. --- gfx/skia/skia/src/core/SkPath.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gfx/skia') diff --git a/gfx/skia/skia/src/core/SkPath.cpp b/gfx/skia/skia/src/core/SkPath.cpp index b7d392025..fc3db3ee5 100644 --- a/gfx/skia/skia/src/core/SkPath.cpp +++ b/gfx/skia/skia/src/core/SkPath.cpp @@ -1744,7 +1744,7 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const { if (this != dst) { dst->fFillType = fFillType; - dst->fConvexity = fConvexity; + dst->fConvexity = kUnknown_Convexity; dst->fIsVolatile = fIsVolatile; } -- cgit v1.2.3