| Index: src/gpu/GrAARectRenderer.cpp | 
| =================================================================== | 
| --- src/gpu/GrAARectRenderer.cpp	(revision 8539) | 
| +++ src/gpu/GrAARectRenderer.cpp	(working copy) | 
| @@ -8,6 +8,7 @@ | 
| #include "GrAARectRenderer.h" | 
| #include "GrRefCnt.h" | 
| #include "GrGpu.h" | 
| +#include "effects/GrRectEffect.h" | 
|  | 
| SK_DEFINE_INST_COUNT(GrAARectRenderer) | 
|  | 
| @@ -181,6 +182,92 @@ | 
| target->resetIndexSource(); | 
| } | 
|  | 
| +struct RectVertex { | 
| +    GrPoint fPos; | 
| +    GrPoint fCenter; | 
| +    GrPoint fDir; | 
| +    GrPoint fWidthHeight; | 
| +}; | 
| + | 
| + | 
| +void GrAARectRenderer::shaderFillAARect(GrGpu* gpu, | 
| +                                        GrDrawTarget* target, | 
| +                                        const GrRect& rect, | 
| +                                        const SkMatrix& combinedMatrix, | 
| +                                        const GrRect& devRect, | 
| +                                        bool useVertexCoverage) { | 
| +    GrDrawState* drawState = target->drawState(); | 
| + | 
| +    SkPoint center = SkPoint::Make(rect.centerX(), rect.centerY()); | 
| +    combinedMatrix.mapPoints(¢er, 1); | 
| + | 
| +    // compute transformed (0, 1) vector | 
| +    SkVector dir = { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScaleY] }; | 
| +    dir.normalize(); | 
| + | 
| +    // compute transformed (width, 0) and (0, height) vectors | 
| +    SkVector vec[2] = { | 
| +      { combinedMatrix[SkMatrix::kMScaleX] * rect.width(), | 
| +	combinedMatrix[SkMatrix::kMSkewY] * rect.width() }, | 
| +      { combinedMatrix[SkMatrix::kMSkewX] * rect.height(), | 
| +	combinedMatrix[SkMatrix::kMScaleY] * rect.height() } | 
| +    }; | 
| + | 
| +    SkScalar newWidth = vec[0].length() / 2.0f + 0.5f; | 
| +    SkScalar newHeight = vec[1].length() / 2.0f + 0.5f; | 
| + | 
| +    static const GrVertexAttrib kVertexAttribs[] = { | 
| +        { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, | 
| +        { kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding }, | 
| +        { kVec2f_GrVertexAttribType, 3*sizeof(GrPoint), kEffect_GrVertexAttribBinding } | 
| +    }; | 
| +    drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs)); | 
| +    GrAssert(sizeof(RectVertex) == drawState->getVertexSize()); | 
| + | 
| +    GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | 
| +    if (!geo.succeeded()) { | 
| +        GrPrintf("Failed to get space for vertices!\n"); | 
| +        return; | 
| +    } | 
| + | 
| +    RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices()); | 
| + | 
| +    enum { | 
| +        // the edge effects share this stage with glyph rendering | 
| +        // (kGlyphMaskStage in GrTextContext) && SW path rendering | 
| +        // (kPathMaskStage in GrSWMaskHelper) | 
| +        kEdgeEffectStage = GrPaint::kTotalStages, | 
| +    }; | 
| + | 
| +    GrEffectRef* effect = GrRectEffect::Create(); | 
| +    static const int kRectAttrIndex = 1; | 
| +    static const int kWidthIndex = 2; | 
| +    drawState->setEffect(kEdgeEffectStage, effect, kRectAttrIndex, kWidthIndex)->unref(); | 
| + | 
| +    for (int i = 0; i < 4; ++i) { | 
| +        verts[i].fCenter = center; | 
| +        verts[i].fDir = dir; | 
| +        verts[i].fWidthHeight.fX = newWidth; | 
| +        verts[i].fWidthHeight.fY = newHeight; | 
| +    } | 
| + | 
| +    SkRect devBounds = { | 
| +        devRect.fLeft   - SK_ScalarHalf, | 
| +        devRect.fTop    - SK_ScalarHalf, | 
| +        devRect.fRight  + SK_ScalarHalf, | 
| +        devRect.fBottom + SK_ScalarHalf | 
| +    }; | 
| + | 
| +    verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop); | 
| +    verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom); | 
| +    verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom); | 
| +    verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop); | 
| + | 
| +    target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); | 
| +    target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6); | 
| +    target->resetIndexSource(); | 
| +} | 
| + | 
| void GrAARectRenderer::strokeAARect(GrGpu* gpu, | 
| GrDrawTarget* target, | 
| const GrRect& devRect, | 
|  |