1/* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7#include "include/core/SkString.h" 8#include "tests/PathOpsDebug.h" 9#include "tests/PathOpsExtendedTest.h" 10#include "tests/PathOpsThreadedCommon.h" 11 12#include <atomic> 13 14static int loopNo = 158; 15static std::atomic<int> gCubicsTestNo{0}; 16 17static void testOpCubicsMain(PathOpsThreadState* data) { 18 SkASSERT(data); 19 const SkPathFillType fts[] = { SkPathFillType::kWinding, SkPathFillType::kEvenOdd }; 20 PathOpsThreadState& state = *data; 21 SkString pathStr; 22 for (int a = 0 ; a < 6; ++a) { 23 for (int b = a + 1 ; b < 7; ++b) { 24 for (int c = 0 ; c < 6; ++c) { 25 for (int d = c + 1 ; d < 7; ++d) { 26 for (auto e : fts) { 27 for (auto f : fts) { 28 SkPath pathA, pathB; 29 pathA.setFillType((SkPathFillType) e); 30 pathA.moveTo(SkIntToScalar(state.fA), SkIntToScalar(state.fB)); 31 pathA.cubicTo(SkIntToScalar(state.fC), SkIntToScalar(state.fD), SkIntToScalar(b), 32 SkIntToScalar(a), SkIntToScalar(d), SkIntToScalar(c)); 33 pathA.close(); 34 pathB.setFillType((SkPathFillType) f); 35 pathB.moveTo(SkIntToScalar(a), SkIntToScalar(b)); 36 pathB.cubicTo(SkIntToScalar(c), SkIntToScalar(d), SkIntToScalar(state.fB), 37 SkIntToScalar(state.fA), SkIntToScalar(state.fD), SkIntToScalar(state.fC)); 38 pathB.close(); 39 for (int op = 0 ; op <= kXOR_SkPathOp; ++op) { 40 if (state.fReporter->verbose()) { 41 pathStr.printf("static void cubicOp%d(skiatest::Reporter* reporter," 42 " const char* filename) {\n", loopNo); 43 pathStr.appendf(" SkPath path, pathB;\n"); 44 pathStr.appendf(" path.setFillType(SkPathFillType::k%s);\n", 45 e == SkPathFillType::kWinding ? "Winding" : e == SkPathFillType::kEvenOdd 46 ? "EvenOdd" : "?UNDEFINED"); 47 pathStr.appendf(" path.moveTo(%d,%d);\n", state.fA, state.fB); 48 pathStr.appendf(" path.cubicTo(%d,%d, %d,%d, %d,%d);\n", state.fC, state.fD, 49 b, a, d, c); 50 pathStr.appendf(" path.close();\n"); 51 pathStr.appendf(" pathB.setFillType(SkPathFillType::k%s);\n", 52 f == SkPathFillType::kWinding ? "Winding" : f == SkPathFillType::kEvenOdd 53 ? "EvenOdd" : "?UNDEFINED"); 54 pathStr.appendf(" pathB.moveTo(%d,%d);\n", a, b); 55 pathStr.appendf(" pathB.cubicTo(%d,%d, %d,%d, %d,%d);\n", c, d, 56 state.fB, state.fA, state.fD, state.fC); 57 pathStr.appendf(" pathB.close();\n"); 58 pathStr.appendf(" testPathOp(reporter, path, pathB, %s, filename);\n", 59 SkPathOpsDebug::OpStr((SkPathOp) op)); 60 pathStr.appendf("}\n"); 61 state.outputProgress(pathStr.c_str(), (SkPathOp) op); 62 } 63 SkString testName; 64 testName.printf("thread_cubics%d", ++gCubicsTestNo); 65 if (!testPathOp(state.fReporter, pathA, pathB, (SkPathOp) op, testName.c_str())) { 66 if (state.fReporter->verbose()) { 67 ++loopNo; 68 goto skipToNext; 69 } 70 } 71 if (PathOpsDebug::gCheckForDuplicateNames) return; 72 } 73 } 74 } 75skipToNext: ; 76 } 77 } 78 } 79 } 80} 81 82DEF_TEST(PathOpsOpCubicsThreaded, reporter) { 83 initializeTests(reporter, "cubicOp"); 84 PathOpsThreadedTestRunner testRunner(reporter); 85 for (int a = 0; a < 6; ++a) { // outermost 86 for (int b = a + 1; b < 7; ++b) { 87 for (int c = 0 ; c < 6; ++c) { 88 for (int d = c + 1; d < 7; ++d) { 89 *testRunner.fRunnables.append() = 90 new PathOpsThreadedRunnable(&testOpCubicsMain, a, b, c, d, &testRunner); 91 } 92 } 93 if (!reporter->allowExtendedTest()) goto finish; 94 } 95 } 96finish: 97 testRunner.render(); 98} 99