예제 #1
0
// 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;
}
예제 #4
0
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;
}
예제 #5
0
static inline bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) {
    return viewMatrix.preservesRightAngles();
}
예제 #6
0
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());
}