DrawAtlasDrawable(DrawAtlasProc proc, const SkRect& r) : fProc(proc), fBounds(r), fUseColors(false) { SkRandom rand; fAtlas = make_atlas(kAtlasSize, kCellSize); const SkScalar kMaxSpeed = 5; const SkScalar cell = SkIntToScalar(kCellSize); int i = 0; for (int y = 0; y < kAtlasSize; y += kCellSize) { for (int x = 0; x < kAtlasSize; x += kCellSize) { const SkScalar sx = SkIntToScalar(x); const SkScalar sy = SkIntToScalar(y); fTex[i].setXYWH(sx, sy, cell, cell); fRec[i].fCenter.set(sx + cell/2, sy + 3*cell/4); fRec[i].fVelocity.fX = rand.nextSScalar1() * kMaxSpeed; fRec[i].fVelocity.fY = rand.nextSScalar1() * kMaxSpeed; fRec[i].fScale = 1; fRec[i].fDScale = rand.nextSScalar1() / 16; fRec[i].fRadian = 0; fRec[i].fDRadian = rand.nextSScalar1() / 8; fRec[i].fAlpha = rand.nextUScalar1(); fRec[i].fDAlpha = rand.nextSScalar1() / 10; i += 1; } } }
static void show_stroke(SkCanvas* canvas, bool doAA, SkScalar strokeWidth, int n) { SkRandom rand; SkPaint paint; paint.setAntiAlias(doAA); paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(strokeWidth); for (int i = 0; i < n; ++i) { SkRect r; SkPath p; r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, rand.nextUScalar1() * W, rand.nextUScalar1() * H); paint.setColor(rand.nextU()); canvas->drawRect(r, paint); r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, rand.nextUScalar1() * W, rand.nextUScalar1() * H); paint.setColor(rand.nextU()); p.addOval(r); canvas->drawPath(p, paint); const SkScalar minx = -SkIntToScalar(W)/4; const SkScalar maxx = 5*SkIntToScalar(W)/4; const SkScalar miny = -SkIntToScalar(H)/4; const SkScalar maxy = 5*SkIntToScalar(H)/4; paint.setColor(rand.nextU()); canvas->drawLine(randRange(rand, minx, maxx), randRange(rand, miny, maxy), randRange(rand, minx, maxx), randRange(rand, miny, maxy), paint); } }
static void show_text(SkCanvas* canvas, bool doAA) { SkRandom rand; SkPaint paint; paint.setAntiAlias(doAA); paint.setLCDRenderText(true); paint.setTextSize(SkIntToScalar(20)); for (int i = 0; i < 200; ++i) { paint.setColor((SK_A32_MASK << SK_A32_SHIFT) | rand.nextU()); canvas->drawText("Hamburgefons", 12, rand.nextSScalar1() * W, rand.nextSScalar1() * H + 20, paint); } }
void onDraw(int loops, SkCanvas*) override { SkRandom r; enum { kMaxObjects = 4 * (1 << 10), }; A* objects[kMaxObjects]; // We delete if a random number [-1, 1] is < the thresh. Otherwise, // we allocate. We start allocate-biased and ping-pong to delete-biased SkScalar delThresh = -SK_ScalarHalf; const int kSwitchThreshPeriod = loops / (2 * kMaxObjects); int s = 0; int count = 0; for (int i = 0; i < loops; i++, ++s) { if (kSwitchThreshPeriod == s) { delThresh = -delThresh; s = 0; } SkScalar del = r.nextSScalar1(); if (count && (kMaxObjects == count || del < delThresh)) { delete objects[count-1]; --count; } else { objects[count] = new A; ++count; } } for (int i = 0; i < count; ++i) { delete objects[i]; } }
MathBench(const char name[]) { fName.printf("math_%s", name); SkRandom rand; for (int i = 0; i < kBuffer; ++i) { fSrc[i] = rand.nextSScalar1(); } }
MathBench(void* param, const char name[]) : INHERITED(param) { fName.printf("math_%s", name); SkRandom rand; for (int i = 0; i < kBuffer; ++i) { fSrc[i] = rand.nextSScalar1(); } }
static int rand_pts(SkRandom& rand, SkPoint pts[4]) { int n = rand.nextU() & 3; n += 1; for (int i = 0; i < n; ++i) { pts[i].fX = rand.nextSScalar1(); pts[i].fY = rand.nextSScalar1(); } return n; }
static void test_conic(skiatest::Reporter* reporter) { SkRandom rand; for (int i = 0; i < 1000; ++i) { SkPoint pts[3]; for (int j = 0; j < 3; ++j) { pts[j].set(rand.nextSScalar1() * 100, rand.nextSScalar1() * 100); } for (int k = 0; k < 10; ++k) { SkScalar w = rand.nextUScalar1() * 2; SkConic conic(pts, w); const SkScalar dt = SK_Scalar1 / 128; SkScalar t = dt; for (int j = 1; j < 128; ++j) { test_conic_eval_pos(reporter, conic, t); test_conic_eval_tan(reporter, conic, t); t += dt; } } } }
static void show_fill(SkCanvas* canvas, bool doAA) { SkRandom rand; SkPaint paint; paint.setAntiAlias(doAA); for (int i = 0; i < 50; ++i) { SkRect r; SkPath p; r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, rand.nextUScalar1() * W, rand.nextUScalar1() * H); paint.setColor(rand.nextU()); canvas->drawRect(r, paint); r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, rand.nextUScalar1() * W, rand.nextUScalar1() * H); paint.setColor(rand.nextU()); p.addOval(r); canvas->drawPath(p, paint); } }
static void test_evalquadat(skiatest::Reporter* reporter) { SkRandom rand; for (int i = 0; i < 1000; ++i) { SkPoint pts[3]; for (int j = 0; j < 3; ++j) { pts[j].set(rand.nextSScalar1() * 100, rand.nextSScalar1() * 100); } const SkScalar dt = SK_Scalar1 / 128; SkScalar t = dt; for (int j = 1; j < 128; ++j) { SkPoint r0; SkEvalQuadAt(pts, t, &r0); SkPoint r1 = SkEvalQuadAt(pts, t); check_pairs(reporter, i, t, "quad-pos", r0.fX, r0.fY, r1.fX, r1.fY); SkVector v0; SkEvalQuadAt(pts, t, nullptr, &v0); SkVector v1 = SkEvalQuadTangentAt(pts, t); check_pairs(reporter, i, t, "quad-tan", v0.fX, v0.fY, v1.fX, v1.fY); t += dt; } } }
static void rand_matrix(SkMatrix* mat, SkRandom& rand, unsigned mask) { mat->setIdentity(); if (mask & SkMatrix::kTranslate_Mask) { mat->postTranslate(rand.nextSScalar1(), rand.nextSScalar1()); } if (mask & SkMatrix::kScale_Mask) { mat->postScale(rand.nextSScalar1(), rand.nextSScalar1()); } if (mask & SkMatrix::kAffine_Mask) { mat->postRotate(rand.nextSScalar1() * 360); } if (mask & SkMatrix::kPerspective_Mask) { mat->setPerspX(rand.nextSScalar1()); mat->setPerspY(rand.nextSScalar1()); } }
virtual void onDraw(SkCanvas* canvas) { // explicitly add spaces, to test a prev. bug const char* text = "Ham bur ge fons"; int len = SkToInt(strlen(text)); SkPath path; SkPaint paint; paint.setAntiAlias(true); sk_tool_utils::set_portable_typeface(&paint); paint.setTextSize(SkIntToScalar(48)); canvas->translate(SkIntToScalar(10), SkIntToScalar(64)); canvas->drawText(text, len, 0, 0, paint); paint.getTextPath(text, len, 0, 0, &path); strokePath(canvas, path); path.reset(); SkAutoTArray<SkPoint> pos(len); SkAutoTArray<SkScalar> widths(len); paint.getTextWidths(text, len, &widths[0]); SkRandom rand; SkScalar x = SkIntToScalar(20); SkScalar y = SkIntToScalar(100); for (int i = 0; i < len; ++i) { pos[i].set(x, y + rand.nextSScalar1() * 24); x += widths[i]; } canvas->translate(0, SkIntToScalar(64)); canvas->drawPosText(text, len, &pos[0], paint); paint.getPosTextPath(text, len, &pos[0], &path); strokePath(canvas, path); }
static void test_matrix_min_max_scale(skiatest::Reporter* reporter) { SkScalar scales[2]; bool success; SkMatrix identity; identity.reset(); REPORTER_ASSERT(reporter, SK_Scalar1 == identity.getMinScale()); REPORTER_ASSERT(reporter, SK_Scalar1 == identity.getMaxScale()); success = identity.getMinMaxScales(scales); REPORTER_ASSERT(reporter, success && SK_Scalar1 == scales[0] && SK_Scalar1 == scales[1]); SkMatrix scale; scale.setScale(SK_Scalar1 * 2, SK_Scalar1 * 4); REPORTER_ASSERT(reporter, SK_Scalar1 * 2 == scale.getMinScale()); REPORTER_ASSERT(reporter, SK_Scalar1 * 4 == scale.getMaxScale()); success = scale.getMinMaxScales(scales); REPORTER_ASSERT(reporter, success && SK_Scalar1 * 2 == scales[0] && SK_Scalar1 * 4 == scales[1]); SkMatrix rot90Scale; rot90Scale.setRotate(90 * SK_Scalar1); rot90Scale.postScale(SK_Scalar1 / 4, SK_Scalar1 / 2); REPORTER_ASSERT(reporter, SK_Scalar1 / 4 == rot90Scale.getMinScale()); REPORTER_ASSERT(reporter, SK_Scalar1 / 2 == rot90Scale.getMaxScale()); success = rot90Scale.getMinMaxScales(scales); REPORTER_ASSERT(reporter, success && SK_Scalar1 / 4 == scales[0] && SK_Scalar1 / 2 == scales[1]); SkMatrix rotate; rotate.setRotate(128 * SK_Scalar1); REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SK_Scalar1, rotate.getMinScale(), SK_ScalarNearlyZero)); REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SK_Scalar1, rotate.getMaxScale(), SK_ScalarNearlyZero)); success = rotate.getMinMaxScales(scales); REPORTER_ASSERT(reporter, success); REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SK_Scalar1, scales[0], SK_ScalarNearlyZero)); REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SK_Scalar1, scales[1], SK_ScalarNearlyZero)); SkMatrix translate; translate.setTranslate(10 * SK_Scalar1, -5 * SK_Scalar1); REPORTER_ASSERT(reporter, SK_Scalar1 == translate.getMinScale()); REPORTER_ASSERT(reporter, SK_Scalar1 == translate.getMaxScale()); success = translate.getMinMaxScales(scales); REPORTER_ASSERT(reporter, success && SK_Scalar1 == scales[0] && SK_Scalar1 == scales[1]); SkMatrix perspX; perspX.reset(); perspX.setPerspX(SkScalarToPersp(SK_Scalar1 / 1000)); REPORTER_ASSERT(reporter, -SK_Scalar1 == perspX.getMinScale()); REPORTER_ASSERT(reporter, -SK_Scalar1 == perspX.getMaxScale()); // Verify that getMinMaxScales() doesn't update the scales array on failure. scales[0] = -5; scales[1] = -5; success = perspX.getMinMaxScales(scales); REPORTER_ASSERT(reporter, !success && -5 * SK_Scalar1 == scales[0] && -5 * SK_Scalar1 == scales[1]); SkMatrix perspY; perspY.reset(); perspY.setPerspY(SkScalarToPersp(-SK_Scalar1 / 500)); REPORTER_ASSERT(reporter, -SK_Scalar1 == perspY.getMinScale()); REPORTER_ASSERT(reporter, -SK_Scalar1 == perspY.getMaxScale()); scales[0] = -5; scales[1] = -5; success = perspY.getMinMaxScales(scales); REPORTER_ASSERT(reporter, !success && -5 * SK_Scalar1 == scales[0] && -5 * SK_Scalar1 == scales[1]); SkMatrix baseMats[] = {scale, rot90Scale, rotate, translate, perspX, perspY}; SkMatrix mats[2*SK_ARRAY_COUNT(baseMats)]; for (size_t i = 0; i < SK_ARRAY_COUNT(baseMats); ++i) { mats[i] = baseMats[i]; bool invertable = mats[i].invert(&mats[i + SK_ARRAY_COUNT(baseMats)]); REPORTER_ASSERT(reporter, invertable); } SkRandom rand; for (int m = 0; m < 1000; ++m) { SkMatrix mat; mat.reset(); for (int i = 0; i < 4; ++i) { int x = rand.nextU() % SK_ARRAY_COUNT(mats); mat.postConcat(mats[x]); } SkScalar minScale = mat.getMinScale(); SkScalar maxScale = mat.getMaxScale(); REPORTER_ASSERT(reporter, (minScale < 0) == (maxScale < 0)); REPORTER_ASSERT(reporter, (maxScale < 0) == mat.hasPerspective()); SkScalar scales[2]; bool success = mat.getMinMaxScales(scales); REPORTER_ASSERT(reporter, success == !mat.hasPerspective()); REPORTER_ASSERT(reporter, !success || (scales[0] == minScale && scales[1] == maxScale)); if (mat.hasPerspective()) { m -= 1; // try another non-persp matrix continue; } // test a bunch of vectors. All should be scaled by between minScale and maxScale // (modulo some error) and we should find a vector that is scaled by almost each. static const SkScalar gVectorScaleTol = (105 * SK_Scalar1) / 100; static const SkScalar gCloseScaleTol = (97 * SK_Scalar1) / 100; SkScalar max = 0, min = SK_ScalarMax; SkVector vectors[1000]; for (size_t i = 0; i < SK_ARRAY_COUNT(vectors); ++i) { vectors[i].fX = rand.nextSScalar1(); vectors[i].fY = rand.nextSScalar1(); if (!vectors[i].normalize()) { i -= 1; continue; } } mat.mapVectors(vectors, SK_ARRAY_COUNT(vectors)); for (size_t i = 0; i < SK_ARRAY_COUNT(vectors); ++i) { SkScalar d = vectors[i].length(); REPORTER_ASSERT(reporter, SkScalarDiv(d, maxScale) < gVectorScaleTol); REPORTER_ASSERT(reporter, SkScalarDiv(minScale, d) < gVectorScaleTol); if (max < d) { max = d; } if (min > d) { min = d; } } REPORTER_ASSERT(reporter, SkScalarDiv(max, maxScale) >= gCloseScaleTol); REPORTER_ASSERT(reporter, SkScalarDiv(minScale, min) >= gCloseScaleTol); } }
void onDelayedSetup() override { SkRandom rand; for (int i = 0; i < N; ++i) { fFloats[i] = 300.0f * (rand.nextSScalar1() + 0.5f); } }
// having unknown values in our arrays can throw off the timing a lot, perhaps // handling NaN values is a lot slower. Anyway, this guy is just meant to put // reasonable values in our arrays. template <typename T> void init9(T array[9]) { SkRandom rand; for (int i = 0; i < 9; i++) { array[i] = rand.nextSScalar1(); } }
void test_matrix_max_stretch(skiatest::Reporter* reporter) { SkMatrix identity; identity.reset(); REPORTER_ASSERT(reporter, SK_Scalar1 == identity.getMaxStretch()); SkMatrix scale; scale.setScale(SK_Scalar1 * 2, SK_Scalar1 * 4); REPORTER_ASSERT(reporter, SK_Scalar1 * 4 == scale.getMaxStretch()); SkMatrix rot90Scale; rot90Scale.setRotate(90 * SK_Scalar1); rot90Scale.postScale(SK_Scalar1 / 4, SK_Scalar1 / 2); REPORTER_ASSERT(reporter, SK_Scalar1 / 2 == rot90Scale.getMaxStretch()); SkMatrix rotate; rotate.setRotate(128 * SK_Scalar1); REPORTER_ASSERT(reporter, SkScalarAbs(SK_Scalar1 - rotate.getMaxStretch()) <= SK_ScalarNearlyZero); SkMatrix translate; translate.setTranslate(10 * SK_Scalar1, -5 * SK_Scalar1); REPORTER_ASSERT(reporter, SK_Scalar1 == translate.getMaxStretch()); SkMatrix perspX; perspX.reset(); perspX.setPerspX(SkScalarToPersp(SK_Scalar1 / 1000)); REPORTER_ASSERT(reporter, -SK_Scalar1 == perspX.getMaxStretch()); SkMatrix perspY; perspY.reset(); perspY.setPerspX(SkScalarToPersp(-SK_Scalar1 / 500)); REPORTER_ASSERT(reporter, -SK_Scalar1 == perspY.getMaxStretch()); SkMatrix baseMats[] = {scale, rot90Scale, rotate, translate, perspX, perspY}; SkMatrix mats[2*SK_ARRAY_COUNT(baseMats)]; for (size_t i = 0; i < SK_ARRAY_COUNT(baseMats); ++i) { mats[i] = baseMats[i]; bool invertable = mats[i].invert(&mats[i + SK_ARRAY_COUNT(baseMats)]); REPORTER_ASSERT(reporter, invertable); } SkRandom rand; for (int m = 0; m < 1000; ++m) { SkMatrix mat; mat.reset(); for (int i = 0; i < 4; ++i) { int x = rand.nextU() % SK_ARRAY_COUNT(mats); mat.postConcat(mats[x]); } SkScalar stretch = mat.getMaxStretch(); if ((stretch < 0) != mat.hasPerspective()) { stretch = mat.getMaxStretch(); } REPORTER_ASSERT(reporter, (stretch < 0) == mat.hasPerspective()); if (mat.hasPerspective()) { m -= 1; // try another non-persp matrix continue; } // test a bunch of vectors. None should be scaled by more than stretch // (modulo some error) and we should find a vector that is scaled by // almost stretch. static const SkScalar gStretchTol = (105 * SK_Scalar1) / 100; static const SkScalar gMaxStretchTol = (97 * SK_Scalar1) / 100; SkScalar max = 0; SkVector vectors[1000]; for (size_t i = 0; i < SK_ARRAY_COUNT(vectors); ++i) { vectors[i].fX = rand.nextSScalar1(); vectors[i].fY = rand.nextSScalar1(); if (!vectors[i].normalize()) { i -= 1; continue; } } mat.mapVectors(vectors, SK_ARRAY_COUNT(vectors)); for (size_t i = 0; i < SK_ARRAY_COUNT(vectors); ++i) { SkScalar d = vectors[i].length(); REPORTER_ASSERT(reporter, SkScalarDiv(d, stretch) < gStretchTol); if (max < d) { max = d; } } REPORTER_ASSERT(reporter, SkScalarDiv(max, stretch) >= gMaxStretchTol); } }