diff options
author | 2015-09-18 07:12:55 -0700 | |
---|---|---|
committer | 2015-09-18 07:12:56 -0700 | |
commit | 3566d44d852b2fc1773e41e80c0c19610aa6d43b (patch) | |
tree | df769ffed9375229721ef454a69527bff63b08fc | |
parent | 966e3d30baf676dc399dc9c97ef15cc2c4f8d461 (diff) |
Move StrokeRectBatches into .cpp files
BUG=skia:
Review URL: https://codereview.chromium.org/1353683003
-rw-r--r-- | gyp/gpu.gypi | 4 | ||||
-rw-r--r-- | src/gpu/GrBatchTest.cpp | 4 | ||||
-rw-r--r-- | src/gpu/batches/GrAAStrokeRectBatch.cpp | 162 | ||||
-rw-r--r-- | src/gpu/batches/GrAAStrokeRectBatch.h | 106 | ||||
-rw-r--r-- | src/gpu/batches/GrNonAAFillRectBatch.cpp | 83 | ||||
-rw-r--r-- | src/gpu/batches/GrNonAAFillRectBatch.h | 8 | ||||
-rw-r--r-- | src/gpu/batches/GrNonAAStrokeRectBatch.cpp | 226 | ||||
-rw-r--r-- | src/gpu/batches/GrNonAAStrokeRectBatch.h | 29 | ||||
-rw-r--r-- | src/gpu/batches/GrRectBatchFactory.cpp | 36 | ||||
-rw-r--r-- | src/gpu/batches/GrRectBatchFactory.h | 22 | ||||
-rw-r--r-- | src/gpu/batches/GrStrokeRectBatch.cpp | 139 | ||||
-rw-r--r-- | src/gpu/batches/GrStrokeRectBatch.h | 83 |
12 files changed, 477 insertions, 425 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index cf2e5dd11c..c9761943b9 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -226,10 +226,10 @@ '<(skia_src_path)/gpu/batches/GrDrawVerticesBatch.h', '<(skia_src_path)/gpu/batches/GrNonAAFillRectBatch.h', '<(skia_src_path)/gpu/batches/GrNonAAFillRectBatch.cpp', + '<(skia_src_path)/gpu/batches/GrNonAAStrokeRectBatch.cpp', + '<(skia_src_path)/gpu/batches/GrNonAAStrokeRectBatch.h', '<(skia_src_path)/gpu/batches/GrRectBatchFactory.h', '<(skia_src_path)/gpu/batches/GrRectBatchFactory.cpp', - '<(skia_src_path)/gpu/batches/GrStrokeRectBatch.cpp', - '<(skia_src_path)/gpu/batches/GrStrokeRectBatch.h', '<(skia_src_path)/gpu/batches/GrStencilAndCoverPathRenderer.cpp', '<(skia_src_path)/gpu/batches/GrStencilAndCoverPathRenderer.h', '<(skia_src_path)/gpu/batches/GrStencilPathBatch.h', diff --git a/src/gpu/GrBatchTest.cpp b/src/gpu/GrBatchTest.cpp index 1fc2ce85d9..344464d717 100644 --- a/src/gpu/GrBatchTest.cpp +++ b/src/gpu/GrBatchTest.cpp @@ -23,7 +23,7 @@ DRAW_BATCH_TEST_EXTERN(CircleBatch); DRAW_BATCH_TEST_EXTERN(DIEllipseBatch); DRAW_BATCH_TEST_EXTERN(EllipseBatch); DRAW_BATCH_TEST_EXTERN(GrDrawAtlasBatch); -DRAW_BATCH_TEST_EXTERN(GrStrokeRectBatch); +DRAW_BATCH_TEST_EXTERN(NonAAStrokeRectBatch); DRAW_BATCH_TEST_EXTERN(RRectBatch); DRAW_BATCH_TEST_EXTERN(TesselatingPathBatch); DRAW_BATCH_TEST_EXTERN(TextBlobBatch); @@ -42,7 +42,7 @@ static BatchTestFunc gTestBatches[] = { DRAW_BATCH_TEST_ENTRY(DIEllipseBatch), DRAW_BATCH_TEST_ENTRY(EllipseBatch), DRAW_BATCH_TEST_ENTRY(GrDrawAtlasBatch), - DRAW_BATCH_TEST_ENTRY(GrStrokeRectBatch), + DRAW_BATCH_TEST_ENTRY(NonAAStrokeRectBatch), DRAW_BATCH_TEST_ENTRY(RRectBatch), DRAW_BATCH_TEST_ENTRY(TesselatingPathBatch), DRAW_BATCH_TEST_ENTRY(TextBlobBatch), diff --git a/src/gpu/batches/GrAAStrokeRectBatch.cpp b/src/gpu/batches/GrAAStrokeRectBatch.cpp index 1a55a0715c..4472b0125b 100644 --- a/src/gpu/batches/GrAAStrokeRectBatch.cpp +++ b/src/gpu/batches/GrAAStrokeRectBatch.cpp @@ -43,7 +43,111 @@ static const GrGeometryProcessor* create_stroke_rect_gp(bool tweakAlphaForCovera return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix); } -void GrAAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) { +class AAStrokeRectBatch : public GrVertexBatch { +public: + DEFINE_BATCH_CLASS_ID + + // TODO support AA rotated stroke rects by copying around view matrices + struct Geometry { + SkRect fDevOutside; + SkRect fDevOutsideAssist; + SkRect fDevInside; + GrColor fColor; + bool fMiterStroke; + }; + + static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& devOutside, + const SkRect& devOutsideAssist, const SkRect& devInside, + bool miterStroke) { + return new AAStrokeRectBatch(color, viewMatrix, devOutside, devOutsideAssist, devInside, + miterStroke); + } + + const char* name() const override { return "AAStrokeRect"; } + + 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->setUnknownSingleComponent(); + } + + SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } + +private: + void onPrepareDraws(Target*) override; + void initBatchTracker(const GrPipelineOptimizations&) override; + + AAStrokeRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& devOutside, + const SkRect& devOutsideAssist, const SkRect& devInside, bool miterStroke) + : INHERITED(ClassID()) { + fBatch.fViewMatrix = viewMatrix; + Geometry& geometry = fGeoData.push_back(); + geometry.fColor = color; + geometry.fDevOutside = devOutside; + geometry.fDevOutsideAssist = devOutsideAssist; + geometry.fDevInside = devInside; + geometry.fMiterStroke = miterStroke; + + // If we have miterstroke then we inset devOutside and outset devOutsideAssist, so we need + // the join for proper bounds + fBounds = geometry.fDevOutside; + fBounds.join(geometry.fDevOutsideAssist); + } + + + static const int kMiterIndexCnt = 3 * 24; + static const int kMiterVertexCnt = 16; + static const int kNumMiterRectsInIndexBuffer = 256; + + static const int kBevelIndexCnt = 48 + 36 + 24; + static const int kBevelVertexCnt = 24; + static const int kNumBevelRectsInIndexBuffer = 256; + + static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider, + bool miterStroke); + + GrColor color() const { return fBatch.fColor; } + bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } + bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; } + bool colorIgnored() const { return fBatch.fColorIgnored; } + const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } + bool miterStroke() const { return fBatch.fMiterStroke; } + bool coverageIgnored() const { return fBatch.fCoverageIgnored; } + + bool onCombineIfPossible(GrBatch* t, const GrCaps&) override; + + void generateAAStrokeRectGeometry(void* vertices, + size_t offset, + size_t vertexStride, + int outerVertexNum, + int innerVertexNum, + GrColor color, + const SkRect& devOutside, + const SkRect& devOutsideAssist, + const SkRect& devInside, + bool miterStroke, + bool tweakAlphaForCoverage) const; + + struct BatchTracker { + SkMatrix fViewMatrix; + GrColor fColor; + bool fUsesLocalCoords; + bool fColorIgnored; + bool fCoverageIgnored; + bool fMiterStroke; + bool fCanTweakAlphaForCoverage; + }; + + BatchTracker fBatch; + SkSTArray<1, Geometry, true> fGeoData; + + typedef GrVertexBatch INHERITED; +}; + +void AAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) { // Handle any color overrides if (!opt.readsColor()) { fGeoData[0].fColor = GrColor_ILLEGAL; @@ -59,7 +163,7 @@ void GrAAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) { fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage(); } -void GrAAStrokeRectBatch::onPrepareDraws(Target* target) { +void AAStrokeRectBatch::onPrepareDraws(Target* target) { bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); SkAutoTUnref<const GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlphaForCoverage, @@ -112,8 +216,8 @@ void GrAAStrokeRectBatch::onPrepareDraws(Target* target) { helper.recordDraw(target); } -const GrIndexBuffer* GrAAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resourceProvider, - bool miterStroke) { +const GrIndexBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resourceProvider, + bool miterStroke) { if (miterStroke) { static const uint16_t gMiterIndices[] = { @@ -203,8 +307,8 @@ const GrIndexBuffer* GrAAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* res } } -bool GrAAStrokeRectBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) { - GrAAStrokeRectBatch* that = t->cast<GrAAStrokeRectBatch>(); +bool AAStrokeRectBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) { + AAStrokeRectBatch* that = t->cast<AAStrokeRectBatch>(); if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), that->bounds(), caps)) { @@ -237,17 +341,17 @@ bool GrAAStrokeRectBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) { return true; } -void GrAAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, - size_t offset, - size_t vertexStride, - int outerVertexNum, - int innerVertexNum, - GrColor color, - const SkRect& devOutside, - const SkRect& devOutsideAssist, - const SkRect& devInside, - bool miterStroke, - bool tweakAlphaForCoverage) const { +void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, + size_t offset, + size_t vertexStride, + int outerVertexNum, + int innerVertexNum, + GrColor color, + const SkRect& devOutside, + const SkRect& devOutsideAssist, + const SkRect& devInside, + bool miterStroke, + bool tweakAlphaForCoverage) const { intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; // We create vertices for four nested rectangles. There are two ramps from 0 to full @@ -350,6 +454,20 @@ void GrAAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, } } +namespace GrAAStrokeRectBatch { + +GrDrawBatch* Create(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& devOutside, + const SkRect& devOutsideAssist, + const SkRect& devInside, + bool miterStroke) { + return AAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutsideAssist, devInside, + miterStroke); +} + +}; + /////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef GR_TEST_UTILS @@ -368,14 +486,10 @@ DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { SkRect inside = outside; inside.inset(strokeWidth, strokeWidth); - GrAAStrokeRectBatch::Geometry geo; - geo.fColor = GrRandomColor(random); - geo.fDevOutside = outside; - geo.fDevOutsideAssist = outsideAssist; - geo.fDevInside = inside; - geo.fMiterStroke = miterStroke; + GrColor color = GrRandomColor(random); - return GrAAStrokeRectBatch::Create(geo, GrTest::TestMatrix(random)); + return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outside, outsideAssist, + inside, miterStroke); } #endif diff --git a/src/gpu/batches/GrAAStrokeRectBatch.h b/src/gpu/batches/GrAAStrokeRectBatch.h index fad5bd9d8d..23f160ec9f 100644 --- a/src/gpu/batches/GrAAStrokeRectBatch.h +++ b/src/gpu/batches/GrAAStrokeRectBatch.h @@ -9,107 +9,21 @@ #define GrAAStrokeRectBatch_DEFINED #include "GrColor.h" -#include "GrTypes.h" -#include "GrVertexBatch.h" -#include "SkMatrix.h" -#include "SkRect.h" +class GrDrawBatch; class GrResourceProvider; +class SkMatrix; +struct SkRect; -class GrAAStrokeRectBatch : public GrVertexBatch { -public: - DEFINE_BATCH_CLASS_ID +namespace GrAAStrokeRectBatch { - // TODO support AA rotated stroke rects by copying around view matrices - struct Geometry { - GrColor fColor; - SkRect fDevOutside; - SkRect fDevOutsideAssist; - SkRect fDevInside; - bool fMiterStroke; - }; +GrDrawBatch* Create(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& devOutside, + const SkRect& devOutsideAssist, + const SkRect& devInside, + bool miterStroke); - static GrDrawBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix) { - return new GrAAStrokeRectBatch(geometry, viewMatrix); - } - - const char* name() const override { return "AAStrokeRect"; } - - 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->setUnknownSingleComponent(); - } - - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } - -private: - void onPrepareDraws(Target*) override; - void initBatchTracker(const GrPipelineOptimizations&) override; - - GrAAStrokeRectBatch(const Geometry& geometry, const SkMatrix& viewMatrix) - : INHERITED(ClassID()) { - fBatch.fViewMatrix = viewMatrix; - fGeoData.push_back(geometry); - - // If we have miterstroke then we inset devOutside and outset devOutsideAssist, so we need - // the join for proper bounds - fBounds = geometry.fDevOutside; - fBounds.join(geometry.fDevOutsideAssist); - } - - - static const int kMiterIndexCnt = 3 * 24; - static const int kMiterVertexCnt = 16; - static const int kNumMiterRectsInIndexBuffer = 256; - - static const int kBevelIndexCnt = 48 + 36 + 24; - static const int kBevelVertexCnt = 24; - static const int kNumBevelRectsInIndexBuffer = 256; - - static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider, - bool miterStroke); - - GrColor color() const { return fBatch.fColor; } - bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } - bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; } - bool colorIgnored() const { return fBatch.fColorIgnored; } - const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } - bool miterStroke() const { return fBatch.fMiterStroke; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } - - bool onCombineIfPossible(GrBatch* t, const GrCaps&) override; - - void generateAAStrokeRectGeometry(void* vertices, - size_t offset, - size_t vertexStride, - int outerVertexNum, - int innerVertexNum, - GrColor color, - const SkRect& devOutside, - const SkRect& devOutsideAssist, - const SkRect& devInside, - bool miterStroke, - bool tweakAlphaForCoverage) const; - - struct BatchTracker { - SkMatrix fViewMatrix; - GrColor fColor; - bool fUsesLocalCoords; - bool fColorIgnored; - bool fCoverageIgnored; - bool fMiterStroke; - bool fCanTweakAlphaForCoverage; - }; - - BatchTracker fBatch; - SkSTArray<1, Geometry, true> fGeoData; - - typedef GrVertexBatch INHERITED; }; - #endif diff --git a/src/gpu/batches/GrNonAAFillRectBatch.cpp b/src/gpu/batches/GrNonAAFillRectBatch.cpp index 6eabba6872..54edb7d7c9 100644 --- a/src/gpu/batches/GrNonAAFillRectBatch.cpp +++ b/src/gpu/batches/GrNonAAFillRectBatch.cpp @@ -188,54 +188,59 @@ typedef GrTInstanceBatch<NonAAFillRectBatchImp> NonAAFillRectBatchSimple; typedef GrTInstanceBatch<NonAAFillRectBatchPerspectiveImp> NonAAFillRectBatchPerspective; namespace GrNonAAFillRectBatch { + GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) { - - /* Perspective has to be handled in a slow path for now */ - if (viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective())) { - NonAAFillRectBatchPerspective* batch = NonAAFillRectBatchPerspective::Create(); - NonAAFillRectBatchPerspective::Geometry& geo = *batch->geometry(); - - geo.fColor = color; - geo.fViewMatrix = viewMatrix; - geo.fRect = rect; - geo.fHasLocalRect = SkToBool(localRect); - geo.fHasLocalMatrix = SkToBool(localMatrix); - if (localMatrix) { - geo.fLocalMatrix = *localMatrix; - } - if (localRect) { - geo.fLocalRect = *localRect; - } - - batch->init(); - return batch; + SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective())); + NonAAFillRectBatchSimple* batch = NonAAFillRectBatchSimple::Create(); + NonAAFillRectBatchSimple::Geometry& geo = *batch->geometry(); + + geo.fColor = color; + geo.fViewMatrix = viewMatrix; + geo.fRect = rect; + + if (localRect && localMatrix) { + geo.fLocalQuad.setFromMappedRect(*localRect, *localMatrix); + } else if (localRect) { + geo.fLocalQuad.set(*localRect); + } else if (localMatrix) { + geo.fLocalQuad.setFromMappedRect(rect, *localMatrix); } else { - // TODO bubble these up as separate calls - NonAAFillRectBatchSimple* batch = NonAAFillRectBatchSimple::Create(); - NonAAFillRectBatchSimple::Geometry& geo = *batch->geometry(); - - geo.fColor = color; - geo.fViewMatrix = viewMatrix; - geo.fRect = rect; - - if (localRect && localMatrix) { - geo.fLocalQuad.setFromMappedRect(*localRect, *localMatrix); - } else if (localRect) { - geo.fLocalQuad.set(*localRect); - } else if (localMatrix) { - geo.fLocalQuad.setFromMappedRect(rect, *localMatrix); - } else { - geo.fLocalQuad.set(rect); - } + geo.fLocalQuad.set(rect); + } + + batch->init(); + return batch; +} - batch->init(); - return batch; +GrDrawBatch* CreateWithPerspective(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect* localRect, + const SkMatrix* localMatrix) { + SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective())); + NonAAFillRectBatchPerspective* batch = NonAAFillRectBatchPerspective::Create(); + NonAAFillRectBatchPerspective::Geometry& geo = *batch->geometry(); + + geo.fColor = color; + geo.fViewMatrix = viewMatrix; + geo.fRect = rect; + geo.fHasLocalRect = SkToBool(localRect); + geo.fHasLocalMatrix = SkToBool(localMatrix); + if (localMatrix) { + geo.fLocalMatrix = *localMatrix; } + if (localRect) { + geo.fLocalRect = *localRect; + } + + batch->init(); + return batch; } + }; /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/batches/GrNonAAFillRectBatch.h b/src/gpu/batches/GrNonAAFillRectBatch.h index ac4ca23b78..ac28d0fb46 100644 --- a/src/gpu/batches/GrNonAAFillRectBatch.h +++ b/src/gpu/batches/GrNonAAFillRectBatch.h @@ -15,11 +15,19 @@ class SkMatrix; struct SkRect; namespace GrNonAAFillRectBatch { + GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix); + +GrDrawBatch* CreateWithPerspective(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect* localRect, + const SkMatrix* localMatrix); + }; #endif diff --git a/src/gpu/batches/GrNonAAStrokeRectBatch.cpp b/src/gpu/batches/GrNonAAStrokeRectBatch.cpp new file mode 100644 index 0000000000..2c5194241a --- /dev/null +++ b/src/gpu/batches/GrNonAAStrokeRectBatch.cpp @@ -0,0 +1,226 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrNonAAStrokeRectBatch.h" + +#include "GrBatchTest.h" +#include "GrBatchFlushState.h" +#include "GrColor.h" +#include "GrDefaultGeoProcFactory.h" +#include "GrVertexBatch.h" +#include "SkRandom.h" + +/* 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]; +} + +class NonAAStrokeRectBatch : public GrVertexBatch { +public: + DEFINE_BATCH_CLASS_ID + + struct Geometry { + SkMatrix fViewMatrix; + SkRect fRect; + SkScalar fStrokeWidth; + GrColor fColor; + }; + + static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, + SkScalar strokeWidth, bool snapToPixelCenters) { + return new NonAAStrokeRectBatch(color, viewMatrix, rect, strokeWidth, snapToPixelCenters); + } + + const char* name() const override { return "GrStrokeRectBatch"; } + + 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); + } + +private: + void onPrepareDraws(Target* target) 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())); + } + + target->initDraw(gp, this->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 = target->makeVertexSpace(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); + target->draw(vertices); + } + + void initBatchTracker(const GrPipelineOptimizations& opt) override { + // Handle any color overrides + if (!opt.readsColor()) { + fGeoData[0].fColor = GrColor_ILLEGAL; + } + opt.getOverrideColorIfSet(&fGeoData[0].fColor); + + // setup batch properties + fBatch.fColorIgnored = !opt.readsColor(); + fBatch.fColor = fGeoData[0].fColor; + fBatch.fUsesLocalCoords = opt.readsLocalCoords(); + fBatch.fCoverageIgnored = !opt.readsCoverage(); + } + + NonAAStrokeRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, + SkScalar strokeWidth, bool snapToPixelCenters) + : INHERITED(ClassID()) { + Geometry& geometry = fGeoData.push_back(); + geometry.fViewMatrix = viewMatrix; + geometry.fRect = rect; + geometry.fStrokeWidth = strokeWidth; + geometry.fColor = color; + + 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(); + } + } + + 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, const GrCaps&) override { + // if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *t->pipeline(), + // t->bounds(), caps)) { + // return false; + // } + // GrStrokeRectBatch* 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; + + typedef GrVertexBatch INHERITED; +}; + +namespace GrNonAAStrokeRectBatch { + +GrDrawBatch* Create(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + SkScalar strokeWidth, + bool snapToPixelCenters) { + return NonAAStrokeRectBatch::Create(color, viewMatrix, rect, strokeWidth, snapToPixelCenters); +} + +}; + +#ifdef GR_TEST_UTILS + +DRAW_BATCH_TEST_DEFINE(NonAAStrokeRectBatch) { + SkMatrix viewMatrix = GrTest::TestMatrix(random); + GrColor color = GrRandomColor(random); + SkRect rect = GrTest::TestRect(random); + SkScalar strokeWidth = random->nextBool() ? 0.0f : 1.0f; + + return NonAAStrokeRectBatch::Create(color, viewMatrix, rect, strokeWidth, random->nextBool()); +} + +#endif diff --git a/src/gpu/batches/GrNonAAStrokeRectBatch.h b/src/gpu/batches/GrNonAAStrokeRectBatch.h new file mode 100644 index 0000000000..ed26353fb6 --- /dev/null +++ b/src/gpu/batches/GrNonAAStrokeRectBatch.h @@ -0,0 +1,29 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrNonAAStrokeRectBatch_DEFINED +#define GrNonAAStrokeRectBatch_DEFINED + +#include "GrColor.h" + +#include "SkTypes.h" + +class GrDrawBatch; +struct SkRect; +class SkMatrix; + +namespace GrNonAAStrokeRectBatch { + +GrDrawBatch* Create(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + SkScalar strokeWidth, + bool snapToPixelCenters); + +}; + +#endif diff --git a/src/gpu/batches/GrRectBatchFactory.cpp b/src/gpu/batches/GrRectBatchFactory.cpp index f01010b21b..eed18ad419 100644 --- a/src/gpu/batches/GrRectBatchFactory.cpp +++ b/src/gpu/batches/GrRectBatchFactory.cpp @@ -8,41 +8,11 @@ #include "GrRectBatchFactory.h" #include "GrAAStrokeRectBatch.h" -#include "GrStrokeRectBatch.h" #include "SkStrokeRec.h" -static GrDrawBatch* create_stroke_aa_batch(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& devOutside, - const SkRect& devOutsideAssist, - const SkRect& devInside, - bool miterStroke) { - GrAAStrokeRectBatch::Geometry geometry; - geometry.fColor = color; - geometry.fDevOutside = devOutside; - geometry.fDevOutsideAssist = devOutsideAssist; - geometry.fDevInside = devInside; - geometry.fMiterStroke = miterStroke; - - return GrAAStrokeRectBatch::Create(geometry, viewMatrix); -} - namespace GrRectBatchFactory { -GrDrawBatch* CreateNonAAStroke(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - SkScalar strokeWidth, - bool snapToPixelCenters) { - GrStrokeRectBatch::Geometry geometry; - geometry.fColor = color; - geometry.fViewMatrix = viewMatrix; - geometry.fRect = rect; - geometry.fStrokeWidth = strokeWidth; - return GrStrokeRectBatch::Create(geometry, snapToPixelCenters); -} - GrDrawBatch* CreateAAStroke(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, @@ -98,8 +68,8 @@ GrDrawBatch* CreateAAStroke(GrColor color, devOutsideAssist.outset(0, ry); } - return create_stroke_aa_batch(color, viewMatrix, devOutside, devOutsideAssist, devInside, - miterStroke); + return GrAAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutsideAssist, devInside, + miterStroke); } GrDrawBatch* CreateAAFillNestedRects(GrColor color, @@ -116,7 +86,7 @@ GrDrawBatch* CreateAAFillNestedRects(GrColor color, return CreateAAFill(color, viewMatrix, devOutside, devOutside); } - return create_stroke_aa_batch(color, viewMatrix, devOutside, devOutside, devInside, true); + return GrAAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutside, devInside, true); } }; diff --git a/src/gpu/batches/GrRectBatchFactory.h b/src/gpu/batches/GrRectBatchFactory.h index 3de8c020f2..fbbc66acbc 100644 --- a/src/gpu/batches/GrRectBatchFactory.h +++ b/src/gpu/batches/GrRectBatchFactory.h @@ -11,9 +11,10 @@ #include "GrAAFillRectBatch.h" #include "GrColor.h" #include "GrNonAAFillRectBatch.h" +#include "GrNonAAStrokeRectBatch.h" +#include "SkMatrix.h" class GrBatch; -class SkMatrix; struct SkRect; class SkStrokeRec; @@ -27,7 +28,12 @@ inline GrDrawBatch* CreateNonAAFill(GrColor color, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) { - return GrNonAAFillRectBatch::Create(color, viewMatrix, rect, localRect, localMatrix); + if (viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective())) { + return GrNonAAFillRectBatch::CreateWithPerspective(color, viewMatrix, rect, localRect, + localMatrix); + } else { + return GrNonAAFillRectBatch::Create(color, viewMatrix, rect, localRect, localMatrix); + } } inline GrDrawBatch* CreateAAFill(GrColor color, @@ -45,11 +51,13 @@ inline GrDrawBatch* CreateAAFill(GrColor color, return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRect); } -GrDrawBatch* CreateNonAAStroke(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - SkScalar strokeWidth, - bool snapToPixelCenters); +inline GrDrawBatch* CreateNonAAStroke(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + SkScalar strokeWidth, + bool snapToPixelCenters) { + return GrNonAAStrokeRectBatch::Create(color, viewMatrix, rect, strokeWidth, snapToPixelCenters); +} GrDrawBatch* CreateAAStroke(GrColor, const SkMatrix& viewMatrix, diff --git a/src/gpu/batches/GrStrokeRectBatch.cpp b/src/gpu/batches/GrStrokeRectBatch.cpp deleted file mode 100644 index 20c754c899..0000000000 --- a/src/gpu/batches/GrStrokeRectBatch.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrStrokeRectBatch.h" -#include "GrBatchTest.h" -#include "GrBatchFlushState.h" -#include "SkRandom.h" - -GrStrokeRectBatch::GrStrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters) - : INHERITED(ClassID()) { - 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 GrPipelineOptimizations& opt) { - // Handle any color overrides - if (!opt.readsColor()) { - fGeoData[0].fColor = GrColor_ILLEGAL; - } - opt.getOverrideColorIfSet(&fGeoData[0].fColor); - - // setup batch properties - fBatch.fColorIgnored = !opt.readsColor(); - fBatch.fColor = fGeoData[0].fColor; - fBatch.fUsesLocalCoords = opt.readsLocalCoords(); - fBatch.fCoverageIgnored = !opt.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::onPrepareDraws(Target* target) { - 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())); - } - - target->initDraw(gp, this->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 = target->makeVertexSpace(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); - target->draw(vertices); -} - -#ifdef GR_TEST_UTILS - -DRAW_BATCH_TEST_DEFINE(GrStrokeRectBatch) { - GrStrokeRectBatch::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 GrStrokeRectBatch::Create(geometry, random->nextBool()); -} - -#endif diff --git a/src/gpu/batches/GrStrokeRectBatch.h b/src/gpu/batches/GrStrokeRectBatch.h deleted file mode 100644 index b1cb8d4ccb..0000000000 --- a/src/gpu/batches/GrStrokeRectBatch.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2015 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrStrokeRectBatch_DEFINED -#define GrStrokeRectBatch_DEFINED - -#include "GrColor.h" -#include "GrDefaultGeoProcFactory.h" -#include "GrVertexBatch.h" - -class GrStrokeRectBatch : public GrVertexBatch { -public: - DEFINE_BATCH_CLASS_ID - - struct Geometry { - GrColor fColor; - SkMatrix fViewMatrix; - SkRect fRect; - SkScalar fStrokeWidth; - }; - - static GrDrawBatch* Create(const Geometry& geometry, bool snapToPixelCenters) { - return new GrStrokeRectBatch(geometry, snapToPixelCenters); - } - - const char* name() const override { return "GrStrokeRectBatch"; } - - 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); - } - -private: - void onPrepareDraws(Target*) override; - void initBatchTracker(const GrPipelineOptimizations&) override; - - GrStrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters); - - 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, const GrCaps&) override { - // if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *t->pipeline(), - // t->bounds(), caps)) { - // return false; - // } - // GrStrokeRectBatch* 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; - - typedef GrVertexBatch INHERITED; -}; - -#endif |