aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkEdgeBuilder.cpp
diff options
context:
space:
mode:
authorGravatar liyuqian <liyuqian@google.com>2016-10-04 11:23:22 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-10-04 11:23:22 -0700
commit38911a7cb53474575e1cd1cb545902b50ee00889 (patch)
treee8186ee1c91bb4f9206457debdb0103c1a38218f /src/core/SkEdgeBuilder.cpp
parent421a3c1cc1b227084c7c84618d0b6a6804faabef (diff)
Resubmit issue 2221103002 to fix the iOS build by declaring the flag in
SkCommonFlags.h TBR=reed@google.com,caryclark@google.com BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2393643002 Review-Url: https://codereview.chromium.org/2393643002
Diffstat (limited to 'src/core/SkEdgeBuilder.cpp')
-rw-r--r--src/core/SkEdgeBuilder.cpp185
1 files changed, 149 insertions, 36 deletions
diff --git a/src/core/SkEdgeBuilder.cpp b/src/core/SkEdgeBuilder.cpp
index af68e0ff65..1a160882d4 100644
--- a/src/core/SkEdgeBuilder.cpp
+++ b/src/core/SkEdgeBuilder.cpp
@@ -7,6 +7,7 @@
#include "SkEdgeBuilder.h"
#include "SkPath.h"
#include "SkEdge.h"
+#include "SkAnalyticEdge.h"
#include "SkEdgeClipper.h"
#include "SkLineClipper.h"
#include "SkGeometry.h"
@@ -62,45 +63,135 @@ SkEdgeBuilder::Combine SkEdgeBuilder::CombineVertical(const SkEdge* edge, SkEdge
return kNo_Combine;
}
-static bool vertical_line(const SkEdge* edge) {
+SkEdgeBuilder::Combine SkEdgeBuilder::CombineVertical(
+ const SkAnalyticEdge* edge, SkAnalyticEdge* last) {
+ SkASSERT(fAnalyticAA);
+ if (last->fCurveCount || last->fDX || edge->fX != last->fX) {
+ return kNo_Combine;
+ }
+ if (edge->fWinding == last->fWinding) {
+ if (edge->fLowerY == last->fUpperY) {
+ last->fUpperY = edge->fUpperY;
+ last->fY = last->fUpperY;
+ return kPartial_Combine;
+ }
+ if (edge->fUpperY == last->fLowerY) {
+ last->fLowerY = edge->fLowerY;
+ return kPartial_Combine;
+ }
+ return kNo_Combine;
+ }
+ if (edge->fUpperY == last->fUpperY) {
+ if (edge->fLowerY == last->fLowerY) {
+ return kTotal_Combine;
+ }
+ if (edge->fLowerY < last->fLowerY) {
+ last->fUpperY = edge->fLowerY;
+ last->fY = last->fUpperY;
+ return kPartial_Combine;
+ }
+ last->fUpperY = last->fLowerY;
+ last->fY = last->fUpperY;
+ last->fLowerY = edge->fLowerY;
+ last->fWinding = edge->fWinding;
+ return kPartial_Combine;
+ }
+ if (edge->fLowerY == last->fLowerY) {
+ if (edge->fUpperY > last->fUpperY) {
+ last->fLowerY = edge->fUpperY;
+ return kPartial_Combine;
+ }
+ last->fLowerY = last->fUpperY;
+ last->fUpperY = edge->fUpperY;
+ last->fY = last->fUpperY;
+ last->fWinding = edge->fWinding;
+ return kPartial_Combine;
+ }
+ return kNo_Combine;
+}
+
+bool SkEdgeBuilder::vertical_line(const SkEdge* edge) {
+ return !edge->fDX && !edge->fCurveCount;
+}
+
+bool SkEdgeBuilder::vertical_line(const SkAnalyticEdge* edge) {
+ SkASSERT(fAnalyticAA);
return !edge->fDX && !edge->fCurveCount;
}
void SkEdgeBuilder::addLine(const SkPoint pts[]) {
- SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc);
- if (edge->setLine(pts[0], pts[1], fShiftUp)) {
- if (vertical_line(edge) && fList.count()) {
- Combine combine = CombineVertical(edge, *(fList.end() - 1));
- if (kNo_Combine != combine) {
- if (kTotal_Combine == combine) {
- fList.pop();
+ if (fAnalyticAA) {
+ SkAnalyticEdge* edge = typedAllocThrow<SkAnalyticEdge>(fAlloc);
+ if (edge->setLine(pts[0], pts[1])) {
+ if (vertical_line(edge) && fList.count()) {
+ Combine combine = CombineVertical(edge, (SkAnalyticEdge*)*(fList.end() - 1));
+ if (kNo_Combine != combine) {
+ if (kTotal_Combine == combine) {
+ fList.pop();
+ }
+ goto unallocate_analytic_edge;
}
- goto unallocate_edge;
}
+ fList.push(edge);
+ } else {
+unallocate_analytic_edge:
+ ;
+ // TODO: unallocate edge from storage...
}
- fList.push(edge);
} else {
+ SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc);
+ if (edge->setLine(pts[0], pts[1], fShiftUp)) {
+ if (vertical_line(edge) && fList.count()) {
+ Combine combine = CombineVertical(edge, (SkEdge*)*(fList.end() - 1));
+ if (kNo_Combine != combine) {
+ if (kTotal_Combine == combine) {
+ fList.pop();
+ }
+ goto unallocate_edge;
+ }
+ }
+ fList.push(edge);
+ } else {
unallocate_edge:
- ;
- // TODO: unallocate edge from storage...
+ ;
+ // TODO: unallocate edge from storage...
+ }
}
}
void SkEdgeBuilder::addQuad(const SkPoint pts[]) {
- SkQuadraticEdge* edge = typedAllocThrow<SkQuadraticEdge>(fAlloc);
- if (edge->setQuadratic(pts, fShiftUp)) {
- fList.push(edge);
+ if (fAnalyticAA) {
+ SkAnalyticQuadraticEdge* edge = typedAllocThrow<SkAnalyticQuadraticEdge>(fAlloc);
+ if (edge->setQuadratic(pts)) {
+ fList.push(edge);
+ } else {
+ // TODO: unallocate edge from storage...
+ }
} else {
- // TODO: unallocate edge from storage...
+ SkQuadraticEdge* edge = typedAllocThrow<SkQuadraticEdge>(fAlloc);
+ if (edge->setQuadratic(pts, fShiftUp)) {
+ fList.push(edge);
+ } else {
+ // TODO: unallocate edge from storage...
+ }
}
}
void SkEdgeBuilder::addCubic(const SkPoint pts[]) {
- SkCubicEdge* edge = typedAllocThrow<SkCubicEdge>(fAlloc);
- if (edge->setCubic(pts, fShiftUp)) {
- fList.push(edge);
+ if (fAnalyticAA) {
+ SkAnalyticCubicEdge* edge = typedAllocThrow<SkAnalyticCubicEdge>(fAlloc);
+ if (edge->setCubic(pts)) {
+ fList.push(edge);
+ } else {
+ // TODO: unallocate edge from storage...
+ }
} else {
- // TODO: unallocate edge from storage...
+ SkCubicEdge* edge = typedAllocThrow<SkCubicEdge>(fAlloc);
+ if (edge->setCubic(pts, fShiftUp)) {
+ fList.push(edge);
+ } else {
+ // TODO: unallocate edge from storage...
+ }
}
}
@@ -135,7 +226,14 @@ static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) {
}
SkEdgeBuilder::Combine SkEdgeBuilder::checkVertical(const SkEdge* edge, SkEdge** edgePtr) {
- return !vertical_line(edge) || edgePtr <= fEdgeList ? kNo_Combine :
+ return !vertical_line(edge) || edgePtr <= (SkEdge**)fEdgeList ? kNo_Combine :
+ CombineVertical(edge, edgePtr[-1]);
+}
+
+SkEdgeBuilder::Combine SkEdgeBuilder::checkVertical(const SkAnalyticEdge* edge,
+ SkAnalyticEdge** edgePtr) {
+ SkASSERT(fAnalyticAA);
+ return !vertical_line(edge) || edgePtr <= (SkAnalyticEdge**)fEdgeList ? kNo_Combine :
CombineVertical(edge, edgePtr[-1]);
}
@@ -152,15 +250,16 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
// segments.
maxEdgeCount *= SkLineClipper::kMaxClippedLineSegments;
}
- size_t maxEdgeSize = maxEdgeCount * sizeof(SkEdge);
- size_t maxEdgePtrSize = maxEdgeCount * sizeof(SkEdge*);
+ size_t edgeSize = fAnalyticAA ? sizeof(SkAnalyticEdge) : sizeof(SkEdge);
+ size_t maxEdgeSize = maxEdgeCount * edgeSize;
+ size_t maxEdgePtrSize = maxEdgeCount * sizeof(char*);
// lets store the edges and their pointers in the same block
char* storage = (char*)fAlloc.allocThrow(maxEdgeSize + maxEdgePtrSize);
- SkEdge* edge = reinterpret_cast<SkEdge*>(storage);
- SkEdge** edgePtr = reinterpret_cast<SkEdge**>(storage + maxEdgeSize);
+ char* edge = (char*)storage;
+ char** edgePtr = (char**)(storage + maxEdgeSize);
// Record the beginning of our pointers, so we can return them to the caller
- fEdgeList = edgePtr;
+ fEdgeList = (void**)edgePtr;
if (iclip) {
SkRect clip;
@@ -178,10 +277,16 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
int lineCount = SkLineClipper::ClipLine(pts, clip, lines, canCullToTheRight);
SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments);
for (int i = 0; i < lineCount; i++) {
- if (edge->setLine(lines[i], lines[i + 1], shiftUp)) {
- Combine combine = checkVertical(edge, edgePtr);
+ bool setLineResult = fAnalyticAA ?
+ ((SkAnalyticEdge*)edge)->setLine(lines[i], lines[i + 1]) :
+ ((SkEdge*)edge)->setLine(lines[i], lines[i + 1], shiftUp);
+ if (setLineResult) {
+ Combine combine = fAnalyticAA ?
+ checkVertical((SkAnalyticEdge*)edge, (SkAnalyticEdge**)edgePtr) :
+ checkVertical((SkEdge*)edge, (SkEdge**)edgePtr);
if (kNo_Combine == combine) {
- *edgePtr++ = edge++;
+ *edgePtr++ = edge;
+ edge += edgeSize;
} else if (kTotal_Combine == combine) {
--edgePtr;
}
@@ -202,16 +307,23 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
// we ignore these, and just get the whole segment from
// the corresponding line/quad/cubic verbs
break;
- case SkPath::kLine_Verb:
- if (edge->setLine(pts[0], pts[1], shiftUp)) {
- Combine combine = checkVertical(edge, edgePtr);
+ case SkPath::kLine_Verb: {
+ bool setLineResult = fAnalyticAA ?
+ ((SkAnalyticEdge*)edge)->setLine(pts[0], pts[1]) :
+ ((SkEdge*)edge)->setLine(pts[0], pts[1], shiftUp);
+ if (setLineResult) {
+ Combine combine = fAnalyticAA ?
+ checkVertical((SkAnalyticEdge*)edge, (SkAnalyticEdge**)edgePtr) :
+ checkVertical((SkEdge*)edge, (SkEdge**)edgePtr);
if (kNo_Combine == combine) {
- *edgePtr++ = edge++;
+ *edgePtr++ = edge;
+ edge += edgeSize;
} else if (kTotal_Combine == combine) {
--edgePtr;
}
}
break;
+ }
default:
SkDEBUGFAIL("unexpected verb");
break;
@@ -219,8 +331,8 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
}
}
SkASSERT((char*)edge <= (char*)fEdgeList);
- SkASSERT(edgePtr - fEdgeList <= maxEdgeCount);
- return SkToInt(edgePtr - fEdgeList);
+ SkASSERT(edgePtr - (char**)fEdgeList <= maxEdgeCount);
+ return SkToInt(edgePtr - (char**)fEdgeList);
}
static void handle_quad(SkEdgeBuilder* builder, const SkPoint pts[3]) {
@@ -232,10 +344,11 @@ static void handle_quad(SkEdgeBuilder* builder, const SkPoint pts[3]) {
}
int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp,
- bool canCullToTheRight) {
+ bool canCullToTheRight, bool analyticAA) {
fAlloc.reset();
fList.reset();
fShiftUp = shiftUp;
+ fAnalyticAA = analyticAA;
if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) {
return this->buildPoly(path, iclip, shiftUp, canCullToTheRight);