// Returns whether or not the gpu can fast path the dash line effect. static bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeInfo, const GrDrawTarget& target, const SkMatrix& viewMatrix) { if (target.getDrawState().getRenderTarget()->isMultisampled()) { return false; } // Pts must be either horizontal or vertical in src space if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) { return false; } // May be able to relax this to include skew. As of now cannot do perspective // because of the non uniform scaling of bloating a rect if (!viewMatrix.preservesRightAngles()) { return false; } if (!strokeInfo.isDashed() || 2 != strokeInfo.dashCount()) { return false; } const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); if (0 == info.fIntervals[0] && 0 == info.fIntervals[1]) { return false; } SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); // Current we do don't handle Round or Square cap dashes if (SkPaint::kRound_Cap == cap && info.fIntervals[0] != 0.f) { return false; } return true; }
void draw(SkCanvas* canvas) { SkPaint p; p.setAntiAlias(true); SkMatrix m; int pos = 0; for (SkScalar sx : { 1, 2 } ) { for (SkScalar kx : { 0, 1 } ) { m.setAll(sx, kx, 16, 0, 1, 32, 0, 0, 1); bool isSimilarity = m.isSimilarity(); bool preservesRightAngles = m.preservesRightAngles(); SkString str; str.printf("sx: %g kx: %g %s %s", sx, kx, isSimilarity ? "sim" : "", preservesRightAngles ? "right" : ""); SkAutoCanvasRestore autoRestore(canvas, true); canvas->concat(m); canvas->drawString(str, 0, pos, p); pos += 20; } } }
inline bool InstancedRendering::selectAntialiasMode(const SkMatrix& viewMatrix, bool antialias, const GrInstancedPipelineInfo& info, bool* useHWAA, AntialiasMode* antialiasMode) { SkASSERT(!info.fColorDisabled || info.fDrawingShapeToStencil); SkASSERT(!info.fIsMixedSampled || info.fIsMultisampled); if (!info.fIsMultisampled || fGpu->caps()->multisampleDisableSupport()) { SkASSERT(fLastSupportedAAMode >= AntialiasMode::kCoverage); if (!antialias) { if (info.fDrawingShapeToStencil && !info.fCanDiscard) { // We can't draw to the stencil buffer without discard (or sample mask if MSAA). return false; } *antialiasMode = AntialiasMode::kNone; *useHWAA = false; return true; } if (info.canUseCoverageAA() && viewMatrix.preservesRightAngles()) { *antialiasMode = AntialiasMode::kCoverage; *useHWAA = false; return true; } } if (info.fIsMultisampled && fLastSupportedAAMode >= AntialiasMode::kMSAA) { if (!info.fIsMixedSampled || info.fColorDisabled) { *antialiasMode = AntialiasMode::kMSAA; *useHWAA = true; return true; } if (fLastSupportedAAMode >= AntialiasMode::kMixedSamples) { *antialiasMode = AntialiasMode::kMixedSamples; *useHWAA = true; return true; } } return false; }
static bool apply_aa_to_rect(GrDrawTarget* target, GrPipelineBuilder* pipelineBuilder, SkRect* devBoundRect, const SkRect& rect, SkScalar strokeWidth, const SkMatrix& combinedMatrix, GrColor color) { if (pipelineBuilder->getRenderTarget()->isUnifiedMultisampled()) { return false; } #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) if (strokeWidth >= 0) { #endif if (!combinedMatrix.preservesAxisAlignment()) { return false; } #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) } else { if (!combinedMatrix.preservesRightAngles()) { return false; } } #endif combinedMatrix.mapRect(devBoundRect, rect); if (!combinedMatrix.rectStaysRect()) { return true; } if (strokeWidth < 0) { return !is_irect(*devBoundRect); } return true; }
static inline bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) { return viewMatrix.preservesRightAngles(); }
static void test_matrix_preserve_shape(skiatest::Reporter* reporter) { SkMatrix mat; // identity mat.setIdentity(); REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // translation only mat.reset(); mat.setTranslate(SkIntToScalar(100), SkIntToScalar(100)); REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // scale with same size mat.reset(); mat.setScale(SkIntToScalar(15), SkIntToScalar(15)); REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // scale with one negative mat.reset(); mat.setScale(SkIntToScalar(-15), SkIntToScalar(15)); REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // scale with different size mat.reset(); mat.setScale(SkIntToScalar(15), SkIntToScalar(20)); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // scale with same size at a pivot point mat.reset(); mat.setScale(SkIntToScalar(15), SkIntToScalar(15), SkIntToScalar(2), SkIntToScalar(2)); REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // scale with different size at a pivot point mat.reset(); mat.setScale(SkIntToScalar(15), SkIntToScalar(20), SkIntToScalar(2), SkIntToScalar(2)); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // skew with same size mat.reset(); mat.setSkew(SkIntToScalar(15), SkIntToScalar(15)); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, !mat.preservesRightAngles()); // skew with different size mat.reset(); mat.setSkew(SkIntToScalar(15), SkIntToScalar(20)); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, !mat.preservesRightAngles()); // skew with same size at a pivot point mat.reset(); mat.setSkew(SkIntToScalar(15), SkIntToScalar(15), SkIntToScalar(2), SkIntToScalar(2)); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, !mat.preservesRightAngles()); // skew with different size at a pivot point mat.reset(); mat.setSkew(SkIntToScalar(15), SkIntToScalar(20), SkIntToScalar(2), SkIntToScalar(2)); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, !mat.preservesRightAngles()); // perspective x mat.reset(); mat.setPerspX(SK_Scalar1 / 2); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, !mat.preservesRightAngles()); // perspective y mat.reset(); mat.setPerspY(SK_Scalar1 / 2); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, !mat.preservesRightAngles()); // rotate for (int angle = 0; angle < 360; ++angle) { mat.reset(); mat.setRotate(SkIntToScalar(angle)); REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); } // see if there are any accumulated precision issues mat.reset(); for (int i = 1; i < 360; i++) { mat.postRotate(SkIntToScalar(1)); } REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // rotate + translate mat.reset(); mat.setRotate(SkIntToScalar(30)); mat.postTranslate(SkIntToScalar(10), SkIntToScalar(20)); REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // rotate + uniform scale mat.reset(); mat.setRotate(SkIntToScalar(30)); mat.postScale(SkIntToScalar(2), SkIntToScalar(2)); REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // rotate + non-uniform scale mat.reset(); mat.setRotate(SkIntToScalar(30)); mat.postScale(SkIntToScalar(3), SkIntToScalar(2)); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, !mat.preservesRightAngles()); // non-uniform scale + rotate mat.reset(); mat.setScale(SkIntToScalar(3), SkIntToScalar(2)); mat.postRotate(SkIntToScalar(30)); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // all zero mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, 0); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, !mat.preservesRightAngles()); // all zero except perspective mat.reset(); mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1); REPORTER_ASSERT(reporter, !mat.isSimilarity()); REPORTER_ASSERT(reporter, !mat.preservesRightAngles()); // scales zero, only skews (rotation) mat.setAll(0, SK_Scalar1, 0, -SK_Scalar1, 0, 0, 0, 0, SkMatrix::I()[8]); REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); // scales zero, only skews (reflection) mat.setAll(0, SK_Scalar1, 0, SK_Scalar1, 0, 0, 0, 0, SkMatrix::I()[8]); REPORTER_ASSERT(reporter, mat.isSimilarity()); REPORTER_ASSERT(reporter, mat.preservesRightAngles()); }