void GrAARectRenderer::fillAARect(GrGpu* gpu, GrDrawTarget* target, const GrRect& devRect, bool useVertexCoverage) { GrVertexLayout layout = aa_rect_layout(useVertexCoverage); size_t vsize = GrDrawState::VertexSize(layout); GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0); if (!geo.succeeded()) { GrPrintf("Failed to get space for vertices!\n"); return; } GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer(gpu); if (NULL == indexBuffer) { GrPrintf("Failed to create index buffer!\n"); return; } intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); set_inset_fan(fan0Pos, vsize, devRect, -SK_ScalarHalf, -SK_ScalarHalf); set_inset_fan(fan1Pos, vsize, devRect, SK_ScalarHalf, SK_ScalarHalf); verts += sizeof(GrPoint); for (int i = 0; i < 4; ++i) { *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; } GrColor innerColor; if (useVertexCoverage) { innerColor = 0xffffffff; } else { innerColor = target->getDrawState().getColor(); } verts += 4 * vsize; for (int i = 0; i < 4; ++i) { *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; } target->setIndexSourceToBuffer(indexBuffer); target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, kVertsPerAAFillRect, kIndicesPerAAFillRect); }
void GrAARectRenderer::strokeAARect(GrGpu* gpu, GrDrawTarget* target, const GrRect& devRect, const GrVec& devStrokeSize, bool useVertexCoverage) { const SkScalar& dx = devStrokeSize.fX; const SkScalar& dy = devStrokeSize.fY; const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); SkScalar spare; { SkScalar w = devRect.width() - dx; SkScalar h = devRect.height() - dy; spare = GrMin(w, h); } if (spare <= 0) { GrRect r(devRect); r.inset(-rx, -ry); this->fillAARect(gpu, target, r, useVertexCoverage); return; } GrVertexLayout layout = aa_rect_layout(useVertexCoverage); size_t vsize = GrDrawTarget::VertexSize(layout); GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0); if (!geo.succeeded()) { GrPrintf("Failed to get space for vertices!\n"); return; } GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(gpu); if (NULL == indexBuffer) { GrPrintf("Failed to create index buffer!\n"); return; } intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); // We create vertices for four nested rectangles. There are two ramps from 0 to full // coverage, one on the exterior of the stroke and the other on the interior. // The following pointers refer to the four rects, from outermost to innermost. GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); set_inset_fan(fan0Pos, vsize, devRect, -rx - SK_ScalarHalf, -ry - SK_ScalarHalf); set_inset_fan(fan1Pos, vsize, devRect, -rx + SK_ScalarHalf, -ry + SK_ScalarHalf); set_inset_fan(fan2Pos, vsize, devRect, rx - SK_ScalarHalf, ry - SK_ScalarHalf); set_inset_fan(fan3Pos, vsize, devRect, rx + SK_ScalarHalf, ry + SK_ScalarHalf); // The outermost rect has 0 coverage verts += sizeof(GrPoint); for (int i = 0; i < 4; ++i) { *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; } // The inner two rects have full coverage GrColor innerColor; if (useVertexCoverage) { innerColor = 0xffffffff; } else { innerColor = target->getDrawState().getColor(); } verts += 4 * vsize; for (int i = 0; i < 8; ++i) { *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; } // The innermost rect has full coverage verts += 8 * vsize; for (int i = 0; i < 4; ++i) { *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; } target->setIndexSourceToBuffer(indexBuffer); target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, aaStrokeRectIndexCount()); }