Give strokerectbatch a proper home
authorbsalomon <bsalomon@google.com>
Wed, 5 Aug 2015 17:34:05 +0000 (10:34 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 5 Aug 2015 17:34:05 +0000 (10:34 -0700)
Review URL: https://codereview.chromium.org/1274763002

gyp/gpu.gypi
src/gpu/GrBatchTest.cpp
src/gpu/GrDrawContext.cpp
src/gpu/GrStrokeRectBatch.cpp [new file with mode: 0644]
src/gpu/GrStrokeRectBatch.h [new file with mode: 0644]

index 07f8d20..d537e4f 100644 (file)
       '<(skia_src_path)/gpu/GrSoftwarePathRenderer.h',
       '<(skia_src_path)/gpu/GrSurfacePriv.h',
       '<(skia_src_path)/gpu/GrSurface.cpp',
+      '<(skia_src_path)/gpu/GrStrokeRectBatch.cpp',
+      '<(skia_src_path)/gpu/GrStrokeRectBatch.h',
       '<(skia_src_path)/gpu/GrTextBlobCache.cpp',
       '<(skia_src_path)/gpu/GrTextBlobCache.h',
       '<(skia_src_path)/gpu/GrTextContext.cpp',
index d19fcaf..1a19041 100644 (file)
@@ -21,8 +21,8 @@ BATCH_TEST_EXTERN(DefaultPathBatch);
 BATCH_TEST_EXTERN(CircleBatch);
 BATCH_TEST_EXTERN(DIEllipseBatch);
 BATCH_TEST_EXTERN(EllipseBatch);
+BATCH_TEST_EXTERN(GrStrokeRectBatch);
 BATCH_TEST_EXTERN(RRectBatch);
-BATCH_TEST_EXTERN(StrokeRectBatch);
 BATCH_TEST_EXTERN(TesselatingPathBatch);
 BATCH_TEST_EXTERN(TextBlobBatch);
 BATCH_TEST_EXTERN(VerticesBatch);
@@ -38,8 +38,8 @@ static BatchTestFunc gTestBatches[] = {
     BATCH_TEST_ENTRY(CircleBatch),
     BATCH_TEST_ENTRY(DIEllipseBatch),
     BATCH_TEST_ENTRY(EllipseBatch),
+    BATCH_TEST_ENTRY(GrStrokeRectBatch),
     BATCH_TEST_ENTRY(RRectBatch),
-    BATCH_TEST_ENTRY(StrokeRectBatch),
     BATCH_TEST_ENTRY(TesselatingPathBatch),
     BATCH_TEST_ENTRY(TextBlobBatch),
     BATCH_TEST_ENTRY(VerticesBatch)
index dff0818..abc2417 100644 (file)
@@ -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:
diff --git a/src/gpu/GrStrokeRectBatch.cpp b/src/gpu/GrStrokeRectBatch.cpp
new file mode 100644 (file)
index 0000000..c33adc0
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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 "SkRandom.h"
+
+#ifdef GR_TEST_UTILS
+
+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/GrStrokeRectBatch.h b/src/gpu/GrStrokeRectBatch.h
new file mode 100644 (file)
index 0000000..6e82c3e
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * 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 "GrBatch.h"
+#include "GrColor.h"
+#include "GrDefaultGeoProcFactory.h"
+
+class GrStrokeRectBatch : public GrBatch {
+public:
+    struct Geometry {
+        GrColor fColor;
+        SkMatrix fViewMatrix;
+        SkRect fRect;
+        SkScalar fStrokeWidth;
+    };
+
+    static GrBatch* Create(const Geometry& geometry, bool snapToPixelCenters) {
+        return SkNEW_ARGS(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);
+    }
+
+    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:
+    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];
+    }
+
+
+    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;
+        //}
+        // 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;
+};
+
+#endif