Move impl of stroke rect batch from h to cpp

Review URL: https://codereview.chromium.org/1275633003
This commit is contained in:
bsalomon 2015-08-05 10:50:01 -07:00 committed by Commit bot
parent ee14a622b0
commit 0e8296eaa6
2 changed files with 120 additions and 116 deletions

View File

@ -9,6 +9,123 @@
#include "GrBatchTest.h"
#include "SkRandom.h"
GrStrokeRectBatch::GrStrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters) {
this->initClassID<GrStrokeRectBatch>();
fBatch.fHairline = geometry.fStrokeWidth == 0;
fGeoData.push_back(geometry);
// setup bounds
fBounds = geometry.fRect;
SkScalar rad = SkScalarHalf(geometry.fStrokeWidth);
fBounds.outset(rad, rad);
geometry.fViewMatrix.mapRect(&fBounds);
// If our caller snaps to pixel centers then we have to round out the bounds
if (snapToPixelCenters) {
fBounds.roundOut();
}
}
void GrStrokeRectBatch::initBatchTracker(const GrPipelineInfo& init) {
// Handle any color overrides
if (!init.readsColor()) {
fGeoData[0].fColor = GrColor_ILLEGAL;
}
init.getOverrideColorIfSet(&fGeoData[0].fColor);
// setup batch properties
fBatch.fColorIgnored = !init.readsColor();
fBatch.fColor = fGeoData[0].fColor;
fBatch.fUsesLocalCoords = init.readsLocalCoords();
fBatch.fCoverageIgnored = !init.readsCoverage();
}
/* create a triangle strip that strokes the specified rect. There are 8
unique vertices, but we repeat the last 2 to close up. Alternatively we
could use an indices array, and then only send 8 verts, but not sure that
would be faster.
*/
static void init_stroke_rect_strip(SkPoint verts[10], const SkRect& rect, SkScalar width) {
const SkScalar rad = SkScalarHalf(width);
// TODO we should be able to enable this assert, but we'd have to filter these draws
// this is a bug
//SkASSERT(rad < rect.width() / 2 && rad < rect.height() / 2);
verts[0].set(rect.fLeft + rad, rect.fTop + rad);
verts[1].set(rect.fLeft - rad, rect.fTop - rad);
verts[2].set(rect.fRight - rad, rect.fTop + rad);
verts[3].set(rect.fRight + rad, rect.fTop - rad);
verts[4].set(rect.fRight - rad, rect.fBottom - rad);
verts[5].set(rect.fRight + rad, rect.fBottom + rad);
verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
verts[8] = verts[0];
verts[9] = verts[1];
}
void GrStrokeRectBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) {
SkAutoTUnref<const GrGeometryProcessor> gp;
{
using namespace GrDefaultGeoProcFactory;
Color color(this->color());
Coverage coverage(this->coverageIgnored() ? Coverage::kSolid_Type :
Coverage::kNone_Type);
LocalCoords localCoords(this->usesLocalCoords() ? LocalCoords::kUsePosition_Type :
LocalCoords::kUnused_Type);
gp.reset(GrDefaultGeoProcFactory::Create(color, coverage, localCoords,
this->viewMatrix()));
}
batchTarget->initDraw(gp, pipeline);
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr));
Geometry& args = fGeoData[0];
int vertexCount = kVertsPerHairlineRect;
if (args.fStrokeWidth > 0) {
vertexCount = kVertsPerStrokeRect;
}
const GrVertexBuffer* vertexBuffer;
int firstVertex;
void* verts = batchTarget->makeVertSpace(vertexStride, vertexCount,
&vertexBuffer, &firstVertex);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return;
}
SkPoint* vertex = reinterpret_cast<SkPoint*>(verts);
GrPrimitiveType primType;
if (args.fStrokeWidth > 0) {;
primType = kTriangleStrip_GrPrimitiveType;
args.fRect.sort();
init_stroke_rect_strip(vertex, args.fRect, args.fStrokeWidth);
} else {
// hairline
primType = kLineStrip_GrPrimitiveType;
vertex[0].set(args.fRect.fLeft, args.fRect.fTop);
vertex[1].set(args.fRect.fRight, args.fRect.fTop);
vertex[2].set(args.fRect.fRight, args.fRect.fBottom);
vertex[3].set(args.fRect.fLeft, args.fRect.fBottom);
vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
}
GrVertices vertices;
vertices.init(primType, vertexBuffer, firstVertex, vertexCount);
batchTarget->draw(vertices);
}
#ifdef GR_TEST_UTILS
BATCH_TEST_DEFINE(GrStrokeRectBatch) {

View File

@ -36,125 +36,12 @@ public:
out->setKnownSingleComponent(0xff);
}
void initBatchTracker(const GrPipelineInfo& init) override {
// Handle any color overrides
if (!init.readsColor()) {
fGeoData[0].fColor = GrColor_ILLEGAL;
}
init.getOverrideColorIfSet(&fGeoData[0].fColor);
void initBatchTracker(const GrPipelineInfo& init) override;
// setup batch properties
fBatch.fColorIgnored = !init.readsColor();
fBatch.fColor = fGeoData[0].fColor;
fBatch.fUsesLocalCoords = init.readsLocalCoords();
fBatch.fCoverageIgnored = !init.readsCoverage();
}
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
SkAutoTUnref<const GrGeometryProcessor> gp;
{
using namespace GrDefaultGeoProcFactory;
Color color(this->color());
Coverage coverage(this->coverageIgnored() ? Coverage::kSolid_Type :
Coverage::kNone_Type);
LocalCoords localCoords(this->usesLocalCoords() ? LocalCoords::kUsePosition_Type :
LocalCoords::kUnused_Type);
gp.reset(GrDefaultGeoProcFactory::Create(color, coverage, localCoords,
this->viewMatrix()));
}
batchTarget->initDraw(gp, pipeline);
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr));
Geometry& args = fGeoData[0];
int vertexCount = kVertsPerHairlineRect;
if (args.fStrokeWidth > 0) {
vertexCount = kVertsPerStrokeRect;
}
const GrVertexBuffer* vertexBuffer;
int firstVertex;
void* verts = batchTarget->makeVertSpace(vertexStride, vertexCount,
&vertexBuffer, &firstVertex);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return;
}
SkPoint* vertex = reinterpret_cast<SkPoint*>(verts);
GrPrimitiveType primType;
if (args.fStrokeWidth > 0) {;
primType = kTriangleStrip_GrPrimitiveType;
args.fRect.sort();
this->setStrokeRectStrip(vertex, args.fRect, args.fStrokeWidth);
} else {
// hairline
primType = kLineStrip_GrPrimitiveType;
vertex[0].set(args.fRect.fLeft, args.fRect.fTop);
vertex[1].set(args.fRect.fRight, args.fRect.fTop);
vertex[2].set(args.fRect.fRight, args.fRect.fBottom);
vertex[3].set(args.fRect.fLeft, args.fRect.fBottom);
vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
}
GrVertices vertices;
vertices.init(primType, vertexBuffer, firstVertex, vertexCount);
batchTarget->draw(vertices);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override;
private:
GrStrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters) {
this->initClassID<GrStrokeRectBatch>();
fBatch.fHairline = geometry.fStrokeWidth == 0;
fGeoData.push_back(geometry);
// setup bounds
fBounds = geometry.fRect;
SkScalar rad = SkScalarHalf(geometry.fStrokeWidth);
fBounds.outset(rad, rad);
geometry.fViewMatrix.mapRect(&fBounds);
// If our caller snaps to pixel centers then we have to round out the bounds
if (snapToPixelCenters) {
fBounds.roundOut();
}
}
/* create a triangle strip that strokes the specified rect. There are 8
unique vertices, but we repeat the last 2 to close up. Alternatively we
could use an indices array, and then only send 8 verts, but not sure that
would be faster.
*/
void setStrokeRectStrip(SkPoint verts[10], const SkRect& rect, SkScalar width) {
const SkScalar rad = SkScalarHalf(width);
// TODO we should be able to enable this assert, but we'd have to filter these draws
// this is a bug
//SkASSERT(rad < rect.width() / 2 && rad < rect.height() / 2);
verts[0].set(rect.fLeft + rad, rect.fTop + rad);
verts[1].set(rect.fLeft - rad, rect.fTop - rad);
verts[2].set(rect.fRight - rad, rect.fTop + rad);
verts[3].set(rect.fRight + rad, rect.fTop - rad);
verts[4].set(rect.fRight - rad, rect.fBottom - rad);
verts[5].set(rect.fRight + rad, rect.fBottom + rad);
verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
verts[8] = verts[0];
verts[9] = verts[1];
}
GrStrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters);
GrColor color() const { return fBatch.fColor; }
bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }