19e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com/* 29e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * Copyright 2012 Google Inc. 39e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * 49e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * Use of this source code is governed by a BSD-style license that can be 59e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com * found in the LICENSE file. 69e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com */ 764334352cc3f29f52dfa07225d65eb218d2fd830skia.committer@gmail.com 8d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com#include "DataTypes.h" 9cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com#include "EdgeWalker_Test.h" 10cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com#include "Intersection_Tests.h" 11cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com#include "SkBitmap.h" 12cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com#include "SkCanvas.h" 1345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#include "SkMatrix.h" 14cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com#include "SkPaint.h" 1559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com#include "SkStream.h" 1659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com 17fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com#include <algorithm> 1859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com#include <errno.h> 1959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com#include <pthread.h> 2059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com#include <unistd.h> 2159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com#include <sys/types.h> 2259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com#include <sys/sysctl.h> 23cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com 2478e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com#undef SkASSERT 2578e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com#define SkASSERT(cond) while (!(cond)) { sk_throw(); } 2678e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com 2759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comstatic const char marker[] = 2859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com "</div>\n" 2959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com "\n" 3059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com "<script type=\"text/javascript\">\n" 3159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com "\n" 3259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com "var testDivs = [\n"; 3324bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com 344eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.comstatic const char* opStrs[] = { 354eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com "kDifference_Op", 364eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com "kIntersect_Op", 374eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com "kUnion_Op", 384eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com "kXor_Op", 394eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com}; 404eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com 414eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.comstatic const char* opSuffixes[] = { 424eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com "d", 434eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com "i", 444eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com "u", 454eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com "x", 464eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com}; 474eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com 4824bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.comstatic const char preferredFilename[] = "/flash/debug/XX.txt"; 4924bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.comstatic const char backupFilename[] = "../../experimental/Intersection/debugXX.txt"; 5059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com 512e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.comstatic bool gShowPath = false; 52198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.comstatic bool gComparePaths = true; 53c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.comstatic bool gShowOutputProgress = false; 544eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.comstatic bool gComparePathsAssert = true; 5559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comstatic bool gPathStrAssert = true; 566aea33f92c611d6fdc88bc2352c5c966168af83bcaryclark@google.comstatic bool gUsePhysicalFiles = false; 57cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com 588f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.comstatic void showPathContour(SkPath::Iter& iter) { 59cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com uint8_t verb; 60cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkPoint pts[4]; 61cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 62cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com switch (verb) { 63cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com case SkPath::kMove_Verb: 64beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com SkDebugf("path.moveTo(%1.9g,%1.9g);\n", pts[0].fX, pts[0].fY); 65cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com continue; 66cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com case SkPath::kLine_Verb: 67beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com SkDebugf("path.lineTo(%1.9g,%1.9g);\n", pts[1].fX, pts[1].fY); 68cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com break; 69cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com case SkPath::kQuad_Verb: 70beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com SkDebugf("path.quadTo(%1.9g,%1.9g, %1.9g,%1.9g);\n", 71cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY); 72cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com break; 73cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com case SkPath::kCubic_Verb: 74beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com SkDebugf("path.cubicTo(%1.9g,%1.9g, %1.9g,%1.9g, %1.9g,%1.9g);\n", 75beda389e646d6be3cfef853584a78ca8ba39d0fccaryclark@google.com pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3].fY); 76cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com break; 77cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com case SkPath::kClose_Verb: 78cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkDebugf("path.close();\n"); 798f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com break; 80cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com default: 81cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkDEBUGFAIL("bad verb"); 82cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com return; 83cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 84cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 85cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com} 86cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com 874eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.comvoid showPath(const SkPath& path, const char* str) { 884eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com SkDebugf("%s\n", !str ? "original:" : str); 89d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com showPath(path); 90d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com} 91d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com 92d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.comvoid showPath(const SkPath& path) { 934eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com SkPath::Iter iter(path, true); 948f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0; 958f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com if (rectCount > 0) { 968f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com SkTDArray<SkRect> rects; 978f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com SkTDArray<SkPath::Direction> directions; 988f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com rects.setCount(rectCount); 998f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com directions.setCount(rectCount); 1008f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com path.rectContours(rects.begin(), directions.begin()); 1018f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com for (int contour = 0; contour < rectCount; ++contour) { 1028f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com const SkRect& rect = rects[contour]; 1034eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop, 1044eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction 1054eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction"); 1064eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com } 1078f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com return; 1084eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com } 1098f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com iter.setPath(path, true); 1108f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com showPathContour(iter); 1114eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com} 1124eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com 113d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.comvoid showPathData(const SkPath& path) { 114d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkPath::Iter iter(path, true); 115d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com uint8_t verb; 116d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkPoint pts[4]; 117d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 118d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com switch (verb) { 119d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com case SkPath::kMove_Verb: 120d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com continue; 121d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com case SkPath::kLine_Verb: 122d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY); 123d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com break; 124d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com case SkPath::kQuad_Verb: 125d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", 126d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY); 127d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com break; 128d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com case SkPath::kCubic_Verb: 129d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", 130d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3].fY); 131d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com break; 132d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com case SkPath::kClose_Verb: 133d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com break; 134d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com default: 135d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkDEBUGFAIL("bad verb"); 136d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com return; 137d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com } 138d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com } 139d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com} 140d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com 141d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.comvoid showOp(const ShapeOp op) { 142d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com switch (op) { 143d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com case kDifference_Op: 144d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkDebugf("op difference\n"); 145d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com break; 146d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com case kIntersect_Op: 147d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkDebugf("op intersect\n"); 148d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com break; 149d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com case kUnion_Op: 150d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkDebugf("op union\n"); 151d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com break; 152d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com case kXor_Op: 153d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkDebugf("op xor\n"); 154d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com break; 155d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com default: 156d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com SkASSERT(0); 157d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com } 158d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com} 159d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com 16045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic void showPath(const SkPath& path, const char* str, const SkMatrix& scale) { 16145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPath scaled; 16245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkMatrix inverse; 16345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com bool success = scale.invert(&inverse); 16445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (!success) SkASSERT(0); 16545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com path.transform(inverse, &scaled); 16645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com showPath(scaled, str); 16745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 16845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 16945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comconst int bitWidth = 64; 17045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comconst int bitHeight = 64; 17122b460cef604c4737b9e221901e1940681255c01skia.committer@gmail.com 17286adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.comstatic void scaleMatrix(const SkPath& one, const SkPath& two, SkMatrix& scale) { 173c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com SkRect larger = one.getBounds(); 174c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com larger.join(two.getBounds()); 175c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com SkScalar largerWidth = larger.width(); 176c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com if (largerWidth < 4) { 177c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com largerWidth = 4; 178c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com } 179c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com SkScalar largerHeight = larger.height(); 180c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com if (largerHeight < 4) { 181c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com largerHeight = 4; 182c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com } 183c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com SkScalar hScale = (bitWidth - 2) / largerWidth; 184c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com SkScalar vScale = (bitHeight - 2) / largerHeight; 185c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com scale.reset(); 186c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com scale.preScale(hScale, vScale); 18786adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com} 188be584d782020fe0d413a9ab4e9a57a13b1ac1032reed@google.com 18986adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.comstatic int pathsDrawTheSame(SkBitmap& bits, const SkPath& scaledOne, const SkPath& scaledTwo, 19086adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com int& error2x2) { 19186adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com if (bits.width() == 0) { 19286adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com bits.setConfig(SkBitmap::kARGB_8888_Config, bitWidth * 2, bitHeight); 19386adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com bits.allocPixels(); 19486adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com } 195be584d782020fe0d413a9ab4e9a57a13b1ac1032reed@google.com SkCanvas canvas(bits); 196cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.drawColor(SK_ColorWHITE); 197cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkPaint paint; 198cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.save(); 19986adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com const SkRect& bounds1 = scaledOne.getBounds(); 200cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1); 201c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com canvas.drawPath(scaledOne, paint); 202cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.restore(); 203cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.save(); 204cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.translate(-bounds1.fLeft + 1 + bitWidth, -bounds1.fTop + 1); 205c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com canvas.drawPath(scaledTwo, paint); 206cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.restore(); 207c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com int errors2 = 0; 208198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com int errors = 0; 209c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com for (int y = 0; y < bitHeight - 1; ++y) { 210cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com uint32_t* addr1 = bits.getAddr32(0, y); 211c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com uint32_t* addr2 = bits.getAddr32(0, y + 1); 212c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com uint32_t* addr3 = bits.getAddr32(bitWidth, y); 213c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com uint32_t* addr4 = bits.getAddr32(bitWidth, y + 1); 214c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com for (int x = 0; x < bitWidth - 1; ++x) { 215c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com // count 2x2 blocks 216c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com bool err = addr1[x] != addr3[x]; 217c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com if (err) { 218c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com errors2 += addr1[x + 1] != addr3[x + 1] 219c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com && addr2[x] != addr4[x] && addr2[x + 1] != addr4[x + 1]; 220c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com errors++; 221c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com } 222cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 223cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 224d1688744d537d928699b6069f99c4470a0f6e772caryclark@google.com if (errors2 >= 6 || errors > 160) { 225c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com SkDebugf("%s errors2=%d errors=%d\n", __FUNCTION__, errors2, errors); 226c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com } 227c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com error2x2 = errors2; 228198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com return errors; 229198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com} 230198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com 23186adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.comstatic int pathsDrawTheSame(const SkPath& one, const SkPath& two, SkBitmap& bits, SkPath& scaledOne, 23286adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com SkPath& scaledTwo, int& error2x2) { 23386adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com SkMatrix scale; 23486adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaleMatrix(one, two, scale); 23586adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com one.transform(scale, &scaledOne); 23686adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com two.transform(scale, &scaledTwo); 23786adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com return pathsDrawTheSame(bits, scaledOne, scaledTwo, error2x2); 23886adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com} 23986adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com 240c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.combool drawAsciiPaths(const SkPath& one, const SkPath& two, bool drawPaths) { 241cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com if (!drawPaths) { 242752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com return true; 243cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 244cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com const SkRect& bounds1 = one.getBounds(); 245cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com const SkRect& bounds2 = two.getBounds(); 246cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkRect larger = bounds1; 247cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com larger.join(bounds2); 248cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkBitmap bits; 249752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com char out[256]; 250cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com int bitWidth = SkScalarCeil(larger.width()) + 2; 251752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com if (bitWidth * 2 + 1 >= (int) sizeof(out)) { 252752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com return false; 253752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com } 254cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com int bitHeight = SkScalarCeil(larger.height()) + 2; 255752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com if (bitHeight >= (int) sizeof(out)) { 256752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com return false; 257752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com } 258cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com bits.setConfig(SkBitmap::kARGB_8888_Config, bitWidth * 2, bitHeight); 259cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com bits.allocPixels(); 260cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkCanvas canvas(bits); 261cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.drawColor(SK_ColorWHITE); 262cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkPaint paint; 263cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.save(); 264cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1); 265cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.drawPath(one, paint); 266cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.restore(); 267cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.save(); 268fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com canvas.translate(-bounds1.fLeft + 1 + bitWidth, -bounds1.fTop + 1); 269cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.drawPath(two, paint); 270cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.restore(); 271cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com for (int y = 0; y < bitHeight; ++y) { 272cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com uint32_t* addr1 = bits.getAddr32(0, y); 273cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com int x; 274cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com char* outPtr = out; 275cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com for (x = 0; x < bitWidth; ++x) { 276cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x'; 277cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 278cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com *outPtr++ = '|'; 279cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com for (x = bitWidth; x < bitWidth * 2; ++x) { 280cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x'; 281cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 282cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com *outPtr++ = '\0'; 283cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkDebugf("%s\n", out); 284cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 285752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com return true; 286cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com} 287cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com 288d21444aab7128c97f4e0eb5e9bf05111d5037292skia.committer@gmail.comstatic void showSimplifiedPath(const SkPath& one, const SkPath& two, 2894eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com const SkPath& scaledOne, const SkPath& scaledTwo) { 2904eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com showPath(one, "original:"); 2914eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com showPath(two, "simplified:"); 2924eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com drawAsciiPaths(scaledOne, scaledTwo, true); 2934eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com} 2944eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com 295be584d782020fe0d413a9ab4e9a57a13b1ac1032reed@google.comint comparePaths(const SkPath& one, const SkPath& two, SkBitmap& bitmap) { 296c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com int errors2x2; 2974eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com SkPath scaledOne, scaledTwo; 2984eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com int errors = pathsDrawTheSame(one, two, bitmap, scaledOne, scaledTwo, errors2x2); 299c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com if (errors2x2 == 0) { 300198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com return 0; 301cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 3028f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com const int MAX_ERRORS = 9; 3034eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) { 3044eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com showSimplifiedPath(one, two, scaledOne, scaledTwo); 3054eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com } 306c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com if (errors2x2 > MAX_ERRORS && gComparePathsAssert) { 307a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com SkDebugf("%s errors=%d\n", __FUNCTION__, errors); 3084eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com showSimplifiedPath(one, two, scaledOne, scaledTwo); 3094eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com SkASSERT(0); 3104eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com } 3114eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com return errors2x2 > MAX_ERRORS ? errors2x2 : 0; 3124eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com} 3134eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com 314d21444aab7128c97f4e0eb5e9bf05111d5037292skia.committer@gmail.comstatic void showShapeOpPath(const SkPath& one, const SkPath& two, const SkPath& a, const SkPath& b, 315044679ef8c08e1f01afadf5bc08251fe8597df81skia.committer@gmail.com const SkPath& scaledOne, const SkPath& scaledTwo, const ShapeOp shapeOp, 31645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com const SkMatrix& scale) { 3174eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com SkASSERT((unsigned) shapeOp < sizeof(opStrs) / sizeof(opStrs[0])); 3184eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com showPath(a, "minuend:"); 3194eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com SkDebugf("op: %s\n", opStrs[shapeOp]); 3204eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com showPath(b, "subtrahend:"); 3214aaaaeace7e617ddc473645756fb7c20790bc270caryclark@google.com // the region often isn't very helpful since it approximates curves with a lot of line-tos 3224aaaaeace7e617ddc473645756fb7c20790bc270caryclark@google.com if (0) showPath(scaledOne, "region:", scale); 3234eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com showPath(two, "op result:"); 3244eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com drawAsciiPaths(scaledOne, scaledTwo, true); 3254eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com} 3264eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com 32745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic int comparePaths(const SkPath& one, const SkPath& scaledOne, const SkPath& two, 32886adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com const SkPath& scaledTwo, 32945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkBitmap& bitmap, const SkPath& a, const SkPath& b, const ShapeOp shapeOp, 33045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com const SkMatrix& scale) { 3314eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com int errors2x2; 33286adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com int errors = pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); 3334eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com if (errors2x2 == 0) { 3344eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com return 0; 3354eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com } 3364eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com const int MAX_ERRORS = 8; 3374eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) { 33845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com showShapeOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale); 3394eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com } 3404eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com if (errors2x2 > MAX_ERRORS && gComparePathsAssert) { 3414eeda37a7456876cb8d509a4ea43c7f4c684477acaryclark@google.com SkDebugf("%s errors=%d\n", __FUNCTION__, errors); 34245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com showShapeOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale); 3432e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com SkASSERT(0); 3442e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com } 345c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com return errors2x2 > MAX_ERRORS ? errors2x2 : 0; 346cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com} 347cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com 348cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com// doesn't work yet 349cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.comvoid comparePathsTiny(const SkPath& one, const SkPath& two) { 350cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com const SkRect& bounds1 = one.getBounds(); 351cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com const SkRect& bounds2 = two.getBounds(); 352cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkRect larger = bounds1; 353cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com larger.join(bounds2); 354cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkBitmap bits; 355cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com int bitWidth = SkScalarCeil(larger.width()) + 2; 356cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com int bitHeight = SkScalarCeil(larger.height()) + 2; 357cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com bits.setConfig(SkBitmap::kA1_Config, bitWidth * 2, bitHeight); 358cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com bits.allocPixels(); 359cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkCanvas canvas(bits); 360cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.drawColor(SK_ColorWHITE); 361cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkPaint paint; 362cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.save(); 363cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1); 364cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.drawPath(one, paint); 365cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.restore(); 366cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.save(); 367cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.translate(-bounds2.fLeft + 1, -bounds2.fTop + 1); 368cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.drawPath(two, paint); 369cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com canvas.restore(); 370cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com for (int y = 0; y < bitHeight; ++y) { 371cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com uint8_t* addr1 = bits.getAddr1(0, y); 372cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com uint8_t* addr2 = bits.getAddr1(bitWidth, y); 3731ab0aac67247bf3ec1f23b220456d316d9a80b45caryclark@google.com for (unsigned x = 0; x < bits.rowBytes(); ++x) { 374cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com SkASSERT(addr1[x] == addr2[x]); 375cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 376cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com } 377cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com} 378cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com 379be584d782020fe0d413a9ab4e9a57a13b1ac1032reed@google.combool testSimplify(const SkPath& path, bool fill, SkPath& out, SkBitmap& bitmap) { 3802e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com if (gShowPath) { 3812e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com showPath(path); 3822e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com } 3832e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com simplify(path, fill, out); 384752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com if (!gComparePaths) { 385752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com return true; 386752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com } 387be584d782020fe0d413a9ab4e9a57a13b1ac1032reed@google.com return comparePaths(path, out, bitmap) == 0; 3882e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com} 38978e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com 39024bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.combool testSimplifyx(SkPath& path, bool useXor, SkPath& out, State4& state, 39159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com const char* pathStr) { 39224bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType; 39324bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com path.setFillType(fillType); 3948dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com if (gShowPath) { 3958dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com showPath(path); 3968dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com } 3978dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com simplifyx(path, out); 3988dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com if (!gComparePaths) { 3998dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com return true; 4008dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com } 401be584d782020fe0d413a9ab4e9a57a13b1ac1032reed@google.com int result = comparePaths(path, out, state.bitmap); 40259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (result && gPathStrAssert) { 403d1688744d537d928699b6069f99c4470a0f6e772caryclark@google.com SkDebugf("addTest %s\n", state.filename); 40459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com char temp[8192]; 40559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com bzero(temp, sizeof(temp)); 40659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com SkMemoryWStream stream(temp, sizeof(temp)); 407b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com const char* pathPrefix = NULL; 408b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com const char* nameSuffix = NULL; 409b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com if (fillType == SkPath::kEvenOdd_FillType) { 410b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n"; 411b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com nameSuffix = "x"; 412b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com } 413b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com const char testFunction[] = "testSimplifyx(path);"; 414b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, stream); 41559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com SkDebugf(temp); 41659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com SkASSERT(0); 41759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 41859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com return result == 0; 4198dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com} 4208dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com 4218dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.combool testSimplifyx(const SkPath& path) { 4228dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com SkPath out; 4238dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com simplifyx(path, out); 4248dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com SkBitmap bitmap; 425be584d782020fe0d413a9ab4e9a57a13b1ac1032reed@google.com int result = comparePaths(path, out, bitmap); 42624bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com if (result && gPathStrAssert) { 42724bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com SkASSERT(0); 42824bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com } 42924bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com return result == 0; 4308dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com} 4318dcf114db9762c02d217beba6e29dffa4e92d298caryclark@google.com 43231143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.combool testShapeOp(const SkPath& a, const SkPath& b, const ShapeOp shapeOp) { 433d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com#if FORCE_RELEASE == 0 434d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com showPathData(a); 435d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com showOp(shapeOp); 436d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com showPathData(b); 437d4c8e1e035bc2edb6caf2c9eac71ef918e60b80bcaryclark@google.com#endif 43831143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com SkPath out; 43931143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com operate(a, b, shapeOp, out); 44086adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com SkPath pathOut, scaledPathOut; 44131143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com SkRegion rgnA, rgnB, openClip, rgnOut; 44231143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com openClip.setRect(-16000, -16000, 16000, 16000); 44331143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com rgnA.setPath(a, openClip); 44431143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com rgnB.setPath(b, openClip); 44531143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com rgnOut.op(rgnA, rgnB, (SkRegion::Op) shapeOp); 44631143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com rgnOut.getBoundaryPath(&pathOut); 44786adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com 44886adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com SkMatrix scale; 44986adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaleMatrix(a, b, scale); 45086adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com SkRegion scaledRgnA, scaledRgnB, scaledRgnOut; 45186adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com SkPath scaledA, scaledB; 45286adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaledA.addPath(a, scale); 45386adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaledA.setFillType(a.getFillType()); 45486adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaledB.addPath(b, scale); 45586adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaledB.setFillType(b.getFillType()); 45686adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaledRgnA.setPath(scaledA, openClip); 45786adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaledRgnB.setPath(scaledB, openClip); 45886adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaledRgnOut.op(scaledRgnA, scaledRgnB, (SkRegion::Op) shapeOp); 45986adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaledRgnOut.getBoundaryPath(&scaledPathOut); 46031143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com SkBitmap bitmap; 46186adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com SkPath scaledOut; 46286adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaledOut.addPath(out, scale); 46386adc0d414496185972a7191aca904e9e7223d7dcaryclark@google.com scaledOut.setFillType(out.getFillType()); 46445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com int result = comparePaths(pathOut, scaledPathOut, out, scaledOut, bitmap, a, b, shapeOp, scale); 46531143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com if (result && gPathStrAssert) { 46631143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com SkASSERT(0); 46731143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com } 46831143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com return result == 0; 46931143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com} 47031143cf37fa38dc98f71c71e518ecc21c83b5e27caryclark@google.com 47159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comconst int maxThreadsAllocated = 64; 47259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comstatic int maxThreads = 1; 47359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comstatic int threadIndex; 47459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comState4 threadState[maxThreadsAllocated]; 47559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comstatic int testNumber; 47659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comstatic const char* testName; 4776aea33f92c611d6fdc88bc2352c5c966168af83bcaryclark@google.comstatic bool debugThreads = false; 47859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com 47959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comState4* State4::queue = NULL; 48059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.compthread_mutex_t State4::addQueue = PTHREAD_MUTEX_INITIALIZER; 48159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.compthread_cond_t State4::checkQueue = PTHREAD_COND_INITIALIZER; 48259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com 48378e17130f396d8b2157116c2504e357192f87ed1caryclark@google.comState4::State4() { 48478e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com bitmap.setConfig(SkBitmap::kARGB_8888_Config, 150 * 2, 100); 48578e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com bitmap.allocPixels(); 48678e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com} 48778e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com 48859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comvoid createThread(State4* statePtr, void* (*testFun)(void* )) { 48959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com int threadError = pthread_create(&statePtr->threadID, NULL, testFun, 49078e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com (void*) statePtr); 49178e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com SkASSERT(!threadError); 49278e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com} 49378e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com 49459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comint dispatchTest4(void* (*testFun)(void* ), int a, int b, int c, int d) { 49559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com int testsRun = 0; 49603f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com State4* statePtr; 49759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (!gRunTestsInOneThread) { 49859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_mutex_lock(&State4::addQueue); 49959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (threadIndex < maxThreads) { 50059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr = &threadState[threadIndex]; 50159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->testsRun = 0; 50259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->a = a; 50359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->b = b; 50459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->c = c; 50559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->d = d; 50659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->done = false; 50759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->index = threadIndex; 50859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->last = false; 50959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (debugThreads) SkDebugf("%s %d create done=%d last=%d\n", __FUNCTION__, 51059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->index, statePtr->done, statePtr->last); 51159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_cond_init(&statePtr->initialized, NULL); 51259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com ++threadIndex; 51359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com createThread(statePtr, testFun); 51459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } else { 51559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com while (!State4::queue) { 51659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (debugThreads) SkDebugf("%s checkQueue\n", __FUNCTION__); 51759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_cond_wait(&State4::checkQueue, &State4::addQueue); 51859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 51959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr = State4::queue; 52059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com testsRun += statePtr->testsRun; 52159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->testsRun = 0; 52259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->a = a; 52359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->b = b; 52459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->c = c; 52559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->d = d; 52659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->done = false; 52759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com State4::queue = NULL; 52859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com for (int index = 0; index < maxThreads; ++index) { 52959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (threadState[index].done) { 53059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com State4::queue = &threadState[index]; 53159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 53259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 53359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (debugThreads) SkDebugf("%s %d init done=%d last=%d queued=%d\n", __FUNCTION__, 53459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com statePtr->index, statePtr->done, statePtr->last, 53559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com State4::queue ? State4::queue->index : -1); 53659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_cond_signal(&statePtr->initialized); 53759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 53859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_mutex_unlock(&State4::addQueue); 53959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } else { 54003f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com statePtr = &threadState[0]; 541c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com testsRun += statePtr->testsRun; 54203f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com statePtr->testsRun = 0; 54303f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com statePtr->a = a; 54403f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com statePtr->b = b; 54503f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com statePtr->c = c; 54603f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com statePtr->d = d; 54703f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com statePtr->done = false; 54803f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com statePtr->index = threadIndex; 54903f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com statePtr->last = false; 55003f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com (*testFun)(statePtr); 55159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 55259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com return testsRun; 55359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com} 55459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com 55559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comvoid initializeTests(const char* test, size_t testNameSize) { 55659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com testName = test; 55759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (!gRunTestsInOneThread) { 55859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com int threads = -1; 55959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com size_t size = sizeof(threads); 56059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com sysctlbyname("hw.logicalcpu_max", &threads, &size, NULL, 0); 56159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (threads > 0) { 56259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com maxThreads = threads; 56359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } else { 56459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com maxThreads = 8; 56559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 56659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 56703f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com SkFILEStream inFile("../../experimental/Intersection/op.htm"); 56803f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com if (inFile.isValid()) { 56903f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com SkTDArray<char> inData; 57003f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com inData.setCount(inFile.getLength()); 57103f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com size_t inLen = inData.count(); 57203f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com inFile.read(inData.begin(), inLen); 57303f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com inFile.setPath(NULL); 574a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com char* insert = strstr(inData.begin(), marker); 57503f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com if (insert) { 57603f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com insert += sizeof(marker) - 1; 57703f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com const char* numLoc = insert + 4 /* indent spaces */ + testNameSize - 1; 57803f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com testNumber = atoi(numLoc) + 1; 57959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 58059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 58124bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com const char* filename = preferredFilename; 58224bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com SkFILEWStream preferredTest(filename); 58324bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com if (!preferredTest.isValid()) { 58424bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com filename = backupFilename; 58524bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com SkFILEWStream backupTest(filename); 58624bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com SkASSERT(backupTest.isValid()); 58724bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com } 58859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com for (int index = 0; index < maxThreads; ++index) { 58959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com State4* statePtr = &threadState[index]; 59059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com strcpy(statePtr->filename, filename); 59124bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com size_t len = strlen(filename); 59224bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com SkASSERT(statePtr->filename[len - 6] == 'X'); 59324bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com SkASSERT(statePtr->filename[len - 5] == 'X'); 59424bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com statePtr->filename[len - 6] = '0' + index / 10; 59524bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com statePtr->filename[len - 5] = '0' + index % 10; 59678e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com } 59778e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com threadIndex = 0; 59878e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com} 59959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com 60024bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.comvoid outputProgress(const State4& state, const char* pathStr, SkPath::FillType pathFillType) { 601c899ad9c7fa28234d99479ab09afb6866bbd8dc3caryclark@google.com if (gRunTestsInOneThread && gShowOutputProgress) { 60203f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com if (pathFillType == SkPath::kEvenOdd_FillType) { 60303f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com SkDebugf(" path.setFillType(SkPath::kEvenOdd_FillType);\n", pathStr); 60459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 60503f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com SkDebugf("%s\n", pathStr); 60603f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com } 607b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com const char testFunction[] = "testSimplifyx(path);"; 608b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com const char* pathPrefix = NULL; 609b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com const char* nameSuffix = NULL; 610b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com if (pathFillType == SkPath::kEvenOdd_FillType) { 611b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n"; 612b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com nameSuffix = "x"; 613b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com } 6146aea33f92c611d6fdc88bc2352c5c966168af83bcaryclark@google.com if (gUsePhysicalFiles) { 6156aea33f92c611d6fdc88bc2352c5c966168af83bcaryclark@google.com SkFILEWStream outFile(state.filename); 6166aea33f92c611d6fdc88bc2352c5c966168af83bcaryclark@google.com if (!outFile.isValid()) { 6176aea33f92c611d6fdc88bc2352c5c966168af83bcaryclark@google.com SkASSERT(0); 6186aea33f92c611d6fdc88bc2352c5c966168af83bcaryclark@google.com return; 6196aea33f92c611d6fdc88bc2352c5c966168af83bcaryclark@google.com } 620b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, outFile); 62103f970652e07c6832cae41fa374cb68ca80d472ccaryclark@google.com return; 62259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 6236aea33f92c611d6fdc88bc2352c5c966168af83bcaryclark@google.com SkFILEWStream outRam(state.filename); 624b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, outRam); 62559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com} 62659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com 627b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.comvoid outputProgress(const State4& state, const char* pathStr, ShapeOp op) { 628b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com SkString testFunc("testShapeOp(path, pathB, "); 629b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com testFunc += opStrs[op]; 630b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com testFunc += ");"; 631b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com const char* testFunction = testFunc.c_str(); 632b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com if (gRunTestsInOneThread && gShowOutputProgress) { 633b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com SkDebugf("%s\n", pathStr); 634b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com SkDebugf(" %s\n", testFunction); 635b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com } 636b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com const char* nameSuffix = opSuffixes[op]; 637b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com if (gUsePhysicalFiles) { 638b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com SkFILEWStream outFile(state.filename); 639b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com if (!outFile.isValid()) { 640b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com SkASSERT(0); 641b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com return; 642b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com } 643b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outputToStream(state, pathStr, NULL, nameSuffix, testFunction, outFile); 644b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com return; 645b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com } 646b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com SkFILEWStream outRam(state.filename); 647b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outputToStream(state, pathStr, NULL, nameSuffix, testFunction, outRam); 648b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com} 649b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com 650b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.comstatic void writeTestName(const char* nameSuffix, SkWStream& outFile) { 65159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText(testName); 65259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeDecAsText(testNumber); 653b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com if (nameSuffix) { 654b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outFile.writeText(nameSuffix); 65524bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com } 65624bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com} 65724bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com 658b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.comvoid outputToStream(const State4& state, const char* pathStr, const char* pathPrefix, 659b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com const char* nameSuffix, 660b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com const char* testFunction, SkWStream& outFile) { 66124bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com outFile.writeText("<div id=\""); 662b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com writeTestName(nameSuffix, outFile); 66359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText("\">\n"); 664b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com if (pathPrefix) { 665b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outFile.writeText(pathPrefix); 66624bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com } 66759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText(pathStr); 66859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText("</div>\n\n"); 669a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com 67059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText(marker); 67159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText(" "); 672b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com writeTestName(nameSuffix, outFile); 67359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText(",\n\n\n"); 674a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com 67559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText("static void "); 676b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com writeTestName(nameSuffix, outFile); 677aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com outFile.writeText("() {\n SkPath path"); 678aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com if (!pathPrefix) { 679aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com outFile.writeText(", pathB"); 680aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com } 681aa35831d1d0e4c798a63fe772430adc4f3a038cdcaryclark@google.com outFile.writeText(";\n"); 682b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com if (pathPrefix) { 683b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outFile.writeText(pathPrefix); 68424bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com } 68559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText(pathStr); 686b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outFile.writeText(" "); 687b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outFile.writeText(testFunction); 688b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com outFile.writeText("\n}\n\n"); 68959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText("static void (*firstTest)() = "); 690b1c42bbdcff20257b30d155fe014d3e04233de45caryclark@google.com writeTestName(nameSuffix, outFile); 69159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText(";\n\n"); 69259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com 69359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText("static struct {\n"); 69459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText(" void (*fun)();\n"); 69559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText(" const char* str;\n"); 69659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText("} tests[] = {\n"); 69759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText(" TEST("); 6988f9f468b0555e95b8fc3cf4e6ee1f1fbf5492a1bcaryclark@google.com writeTestName(nameSuffix, outFile); 69959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.writeText("),\n"); 70059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com outFile.flush(); 70159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com} 70259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com 70359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.combool runNextTestSet(State4& state) { 70459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (gRunTestsInOneThread) { 70559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com return false; 70659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 70759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_mutex_lock(&State4::addQueue); 70859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com state.done = true; 70959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com State4::queue = &state; 71059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (debugThreads) SkDebugf("%s %d checkQueue done=%d last=%d\n", __FUNCTION__, state.index, 71159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com state.done, state.last); 71259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_cond_signal(&State4::checkQueue); 71359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com while (state.done && !state.last) { 71459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (debugThreads) SkDebugf("%s %d done=%d last=%d\n", __FUNCTION__, state.index, state.done, state.last); 71559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_cond_wait(&state.initialized, &State4::addQueue); 71659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 71759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_mutex_unlock(&State4::addQueue); 71859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com return !state.last; 71959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com} 72059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com 72159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.comint waitForCompletion() { 72259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com int testsRun = 0; 72359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (!gRunTestsInOneThread) { 72459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_mutex_lock(&State4::addQueue); 72559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com int runningThreads = maxThreads; 72659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com int index; 72759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com while (runningThreads > 0) { 72859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com while (!State4::queue) { 72959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (debugThreads) SkDebugf("%s checkQueue\n", __FUNCTION__); 73059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_cond_wait(&State4::checkQueue, &State4::addQueue); 73159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 73259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com while (State4::queue) { 73359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com --runningThreads; 73459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com SkDebugf("•"); 73559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com State4::queue->last = true; 73624bec79d6f3d71ff97b50db72461a3892bd4f6b5caryclark@google.com State4* next = NULL; 73759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com for (index = 0; index < maxThreads; ++index) { 73859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com State4& test = threadState[index]; 73959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (test.done && !test.last) { 74059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com next = &test; 74159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 74259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 74359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com if (debugThreads) SkDebugf("%s %d next=%d deQueue\n", __FUNCTION__, 74459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com State4::queue->index, next ? next->index : -1); 74559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_cond_signal(&State4::queue->initialized); 74659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com State4::queue = next; 74759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 74859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 74959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_mutex_unlock(&State4::addQueue); 75059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com for (index = 0; index < maxThreads; ++index) { 75159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com pthread_join(threadState[index].threadID, NULL); 75259823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com testsRun += threadState[index].testsRun; 75359823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 75459823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com SkDebugf("\n"); 75559823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com } 75659823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com#ifdef SK_DEBUG 75759823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com gDebugMaxWindSum = SK_MaxS32; 75859823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com gDebugMaxWindValue = SK_MaxS32; 75959823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com#endif 76059823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com return testsRun; 76159823f7f3ba43c7c6bc1fa8c600b093ecb4236aacaryclark@google.com} 762