diff options
author | 2015-08-05 10:34:05 -0700 | |
---|---|---|
committer | 2015-08-05 10:34:05 -0700 | |
commit | ee14a622b0e12be34f621495daf308a17d80cc7b (patch) | |
tree | 8bebb62124147865d81daf2690e228f31971b1b5 /src/gpu/GrDrawContext.cpp | |
parent | 847029043ec48c150a07e44ffff15151a394f888 (diff) |
Give strokerectbatch a proper home
Review URL: https://codereview.chromium.org/1274763002
Diffstat (limited to 'src/gpu/GrDrawContext.cpp')
-rw-r--r-- | src/gpu/GrDrawContext.cpp | 192 |
1 files changed, 3 insertions, 189 deletions
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index dff0818d3a..abc2417fd6 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -16,6 +16,7 @@ #include "GrPathRenderer.h" #include "GrRenderTarget.h" #include "GrRenderTargetPriv.h" +#include "GrStrokeRectBatch.h" #include "GrStencilAndCoverTextContext.h" #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext) @@ -235,183 +236,6 @@ static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po point.fY >= rect.fTop && point.fY <= rect.fBottom; } -class StrokeRectBatch : public GrBatch { -public: - struct Geometry { - GrColor fColor; - SkMatrix fViewMatrix; - SkRect fRect; - SkScalar fStrokeWidth; - }; - - static GrBatch* Create(const Geometry& geometry, bool snapToPixelCenters) { - return SkNEW_ARGS(StrokeRectBatch, (geometry, snapToPixelCenters)); - } - - const char* name() const override { return "StrokeRectBatch"; } - - void getInvariantOutputColor(GrInitInvariantOutput* out) const override { - // When this is called on a batch, there is only one geometry bundle - out->setKnownFourComponents(fGeoData[0].fColor); - } - - void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { - 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); - - // 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; } - -private: - StrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters) { - this->initClassID<StrokeRectBatch>(); - - 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]; - } - - - GrColor color() const { return fBatch.fColor; } - bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } - bool colorIgnored() const { return fBatch.fColorIgnored; } - const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } - bool hairline() const { return fBatch.fHairline; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } - - bool onCombineIfPossible(GrBatch* t) override { - //if (!this->pipeline()->isEqual(*t->pipeline())) { - // return false; - //} - // StrokeRectBatch* that = t->cast<StrokeRectBatch>(); - - // NonAA stroke rects cannot batch right now - // TODO make these batchable - return false; - } - - struct BatchTracker { - GrColor fColor; - bool fUsesLocalCoords; - bool fColorIgnored; - bool fCoverageIgnored; - bool fHairline; - }; - - const static int kVertsPerHairlineRect = 5; - const static int kVertsPerStrokeRect = 10; - - BatchTracker fBatch; - SkSTArray<1, Geometry, true> fGeoData; -}; - void GrDrawContext::drawRect(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, @@ -499,7 +323,7 @@ void GrDrawContext::drawRect(GrRenderTarget* rt, } if (width >= 0) { - StrokeRectBatch::Geometry geometry; + GrStrokeRectBatch::Geometry geometry; geometry.fViewMatrix = viewMatrix; geometry.fColor = color; geometry.fRect = rect; @@ -507,7 +331,7 @@ void GrDrawContext::drawRect(GrRenderTarget* rt, // Non-AA hairlines are snapped to pixel centers to make which pixels are hit deterministic bool snapToPixelCenters = (0 == width && !rt->isUnifiedMultisampled()); - SkAutoTUnref<GrBatch> batch(StrokeRectBatch::Create(geometry, snapToPixelCenters)); + SkAutoTUnref<GrBatch> batch(GrStrokeRectBatch::Create(geometry, snapToPixelCenters)); // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of // hairline rects. We jam all the vertices to pixel centers to avoid this, but not when MSAA @@ -1204,16 +1028,6 @@ void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch #ifdef GR_TEST_UTILS -BATCH_TEST_DEFINE(StrokeRectBatch) { - StrokeRectBatch::Geometry geometry; - geometry.fViewMatrix = GrTest::TestMatrix(random); - geometry.fColor = GrRandomColor(random); - geometry.fRect = GrTest::TestRect(random); - geometry.fStrokeWidth = random->nextBool() ? 0.0f : 1.0f; - - return StrokeRectBatch::Create(geometry, random->nextBool()); -} - static uint32_t seed_vertices(GrPrimitiveType type) { switch (type) { case kTriangles_GrPrimitiveType: |