AADistanceFieldPathRenderer unit tests
authorjoshualitt <joshualitt@chromium.org>
Mon, 11 May 2015 14:21:37 +0000 (07:21 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 11 May 2015 14:21:37 +0000 (07:21 -0700)
TBR=bsalomon@google.com
BUG=skia:

Review URL: https://codereview.chromium.org/1129083005

include/gpu/GrTestUtils.h
src/gpu/GrAADistanceFieldPathRenderer.cpp
src/gpu/GrAADistanceFieldPathRenderer.h
src/gpu/GrOvalRenderer.cpp
src/gpu/GrTestUtils.cpp

index 2109ad6..21db543 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "GrColor.h"
 #include "SkRandom.h"
+#include "SkStrokeRec.h"
 
 class SkMatrix;
 class SkPath;
@@ -31,6 +32,7 @@ const SkMatrix& TestMatrixInvertible(SkRandom*);
 const SkRect& TestRect(SkRandom*);
 const SkRRect& TestRRectSimple(SkRandom*);
 const SkPath& TestPath(SkRandom*);
+SkStrokeRec TestStrokeRec(SkRandom*);
 
 }
 
index 3d4a89b..3e054d1 100755 (executable)
@@ -10,6 +10,7 @@
 
 #include "GrBatch.h"
 #include "GrBatchTarget.h"
+#include "GrBatchTest.h"
 #include "GrContext.h"
 #include "GrPipelineBuilder.h"
 #include "GrResourceProvider.h"
@@ -553,6 +554,28 @@ private:
     PathDataList* fPathList;
 };
 
+static GrBatchAtlas* create_atlas(GrContext* context, GrBatchAtlas::EvictionFunc func, void* data) {
+    GrBatchAtlas* atlas;
+    // Create a new atlas
+    GrSurfaceDesc desc;
+    desc.fFlags = kNone_GrSurfaceFlags;
+    desc.fWidth = ATLAS_TEXTURE_WIDTH;
+    desc.fHeight = ATLAS_TEXTURE_HEIGHT;
+    desc.fConfig = kAlpha_8_GrPixelConfig;
+
+    // We don't want to flush the context so we claim we're in the middle of flushing so as to
+    // guarantee we do not recieve a texture with pending IO
+    GrTexture* texture = context->textureProvider()->refScratchTexture(
+        desc, GrTextureProvider::kApprox_ScratchTexMatch, true);
+    if (texture) {
+        atlas = SkNEW_ARGS(GrBatchAtlas, (texture, NUM_PLOTS_X, NUM_PLOTS_Y));
+    } else {
+        return NULL;
+    }
+    atlas->registerEvictionCallback(func, data);
+    return atlas;
+}
+
 bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target,
                                                GrPipelineBuilder* pipelineBuilder,
                                                GrColor color,
@@ -568,24 +591,11 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target,
     SkASSERT(fContext);
 
     if (!fAtlas) {
-        // Create a new atlas
-        GrSurfaceDesc desc;
-        desc.fFlags = kNone_GrSurfaceFlags;
-        desc.fWidth = ATLAS_TEXTURE_WIDTH;
-        desc.fHeight = ATLAS_TEXTURE_HEIGHT;
-        desc.fConfig = kAlpha_8_GrPixelConfig;
-
-        // We don't want to flush the context so we claim we're in the middle of flushing so as to
-        // guarantee we do not recieve a texture with pending IO
-        GrTexture* texture = fContext->textureProvider()->refScratchTexture(
-            desc, GrTextureProvider::kApprox_ScratchTexMatch, true);
-        if (texture) {
-            fAtlas = SkNEW_ARGS(GrBatchAtlas, (texture, NUM_PLOTS_X, NUM_PLOTS_Y));
-        } else {
+        fAtlas = create_atlas(fContext, &GrAADistanceFieldPathRenderer::HandleEviction,
+                              (void*)this);
+        if (!fAtlas) {
             return false;
         }
-        fAtlas->registerEvictionCallback(&GrAADistanceFieldPathRenderer::HandleEviction,
-                                         (void*)this);
     }
 
     AADistanceFieldPathBatch::Geometry geometry(stroke.getStrokeRec());
@@ -599,3 +609,72 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target,
     return true;
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef GR_TEST_UTILS
+
+struct PathTestStruct {
+    typedef GrAADistanceFieldPathRenderer::PathCache PathCache;
+    typedef GrAADistanceFieldPathRenderer::PathData PathData;
+    typedef GrAADistanceFieldPathRenderer::PathDataList PathDataList;
+    PathTestStruct() : fContextID(SK_InvalidGenID), fAtlas(NULL) {}
+    ~PathTestStruct() { this->reset(); }
+
+    void reset() {
+        PathDataList::Iter iter;
+        iter.init(fPathList, PathDataList::Iter::kHead_IterStart);
+        PathData* pathData;
+        while ((pathData = iter.get())) {
+            iter.next();
+            fPathList.remove(pathData);
+            SkDELETE(pathData);
+        }
+        SkDELETE(fAtlas);
+    }
+
+    static void HandleEviction(GrBatchAtlas::AtlasID id, void* pr) {
+        PathTestStruct* dfpr = (PathTestStruct*)pr;
+        // remove any paths that use this plot
+        PathDataList::Iter iter;
+        iter.init(dfpr->fPathList, PathDataList::Iter::kHead_IterStart);
+        PathData* pathData;
+        while ((pathData = iter.get())) {
+            iter.next();
+            if (id == pathData->fID) {
+                dfpr->fPathCache.remove(pathData->fKey);
+                dfpr->fPathList.remove(pathData);
+                SkDELETE(pathData);
+            }
+        }
+    }
+
+    uint32_t fContextID;
+    GrBatchAtlas* fAtlas;
+    PathCache fPathCache;
+    PathDataList fPathList;
+};
+
+BATCH_TEST_DEFINE(AADistanceFieldPathRenderer) {
+    static PathTestStruct gTestStruct;
+
+    if (context->uniqueID() != gTestStruct.fContextID) {
+        gTestStruct.fContextID = context->uniqueID();
+        gTestStruct.reset();
+        gTestStruct.fAtlas = create_atlas(context, &PathTestStruct::HandleEviction,
+                                          (void*)&gTestStruct);
+    }
+
+    SkMatrix viewMatrix = GrTest::TestMatrix(random);
+    GrColor color = GrRandomColor(random);
+
+    AADistanceFieldPathBatch::Geometry geometry(GrTest::TestStrokeRec(random));
+    geometry.fPath = GrTest::TestPath(random);
+    geometry.fAntiAlias = random->nextBool();
+
+    return AADistanceFieldPathBatch::Create(geometry, color, viewMatrix,
+                                            gTestStruct.fAtlas,
+                                            &gTestStruct.fPathCache,
+                                            &gTestStruct.fPathList);
+}
+
+#endif
index 6cbee1f..bb76eff 100755 (executable)
@@ -72,16 +72,18 @@ private:
 
     static void HandleEviction(GrBatchAtlas::AtlasID, void*);
 
+    typedef SkTDynamicHash<PathData, PathData::Key> PathCache;
     typedef SkTInternalLList<PathData> PathDataList;
     
     GrContext*                         fContext;
     GrBatchAtlas*                      fAtlas;
-    SkTDynamicHash<PathData, PathData::Key> fPathCache;
+    PathCache                          fPathCache;
     PathDataList                       fPathList;
     
     typedef GrPathRenderer INHERITED;
 
     friend class AADistanceFieldPathBatch;
+    friend struct PathTestStruct;
 };
 
 #endif
index 886159c..ebac42f 100644 (file)
@@ -2090,22 +2090,13 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
 
 #ifdef GR_TEST_UTILS
 
-static SkStrokeRec random_strokerec(SkRandom* random) {
-    SkStrokeRec::InitStyle style =
-            SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1));
-    SkStrokeRec rec(style);
-    bool strokeAndFill = random->nextBool();
-    SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f;
-    rec.setStrokeStyle(strokeWidth, strokeAndFill);
-    return rec;
-}
-
 BATCH_TEST_DEFINE(CircleBatch) {
     SkMatrix viewMatrix = GrTest::TestMatrix(random);
     GrColor color = GrRandomColor(random);
     bool useCoverageAA = random->nextBool();
     SkRect circle = GrTest::TestRect(random);
-    return create_circle_batch(color, viewMatrix, useCoverageAA, circle, random_strokerec(random));
+    return create_circle_batch(color, viewMatrix, useCoverageAA, circle,
+                               GrTest::TestStrokeRec(random));
 }
 
 BATCH_TEST_DEFINE(EllipseBatch) {
@@ -2114,7 +2105,7 @@ BATCH_TEST_DEFINE(EllipseBatch) {
     bool useCoverageAA = random->nextBool();
     SkRect ellipse = GrTest::TestRect(random);
     return create_ellipse_batch(color, viewMatrix, useCoverageAA, ellipse,
-                                random_strokerec(random));
+                                GrTest::TestStrokeRec(random));
 }
 
 BATCH_TEST_DEFINE(DIEllipseBatch) {
@@ -2123,14 +2114,14 @@ BATCH_TEST_DEFINE(DIEllipseBatch) {
     bool useCoverageAA = random->nextBool();
     SkRect ellipse = GrTest::TestRect(random);
     return create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse,
-                                  random_strokerec(random));
+                                  GrTest::TestStrokeRec(random));
 }
 
 BATCH_TEST_DEFINE(RRectBatch) {
     SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random);
     GrColor color = GrRandomColor(random);
     const SkRRect& rrect = GrTest::TestRRectSimple(random);
-    return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random));
+    return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(random));
 }
 
 #endif
index 0bb4044..39f4834 100644 (file)
@@ -175,6 +175,21 @@ const SkPath& TestPath(SkRandom* random) {
     return gPath[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gPath)))];
 }
 
+SkStrokeRec TestStrokeRec(SkRandom* random) {
+    SkStrokeRec::InitStyle style =
+            SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1));
+    SkStrokeRec rec(style);
+    bool strokeAndFill = random->nextBool();
+    SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f;
+    rec.setStrokeStyle(strokeWidth, strokeAndFill);
+
+    SkPaint::Cap cap = SkPaint::Cap(random->nextULessThan(SkPaint::kCapCount));
+    SkPaint::Join join = SkPaint::Join(random->nextULessThan(SkPaint::kJoinCount));
+    SkScalar miterLimit = random->nextRangeScalar(1.f, 5.f);
+    rec.setStrokeParams(cap, join, miterLimit);
+    return rec;
+}
+
 };
 
 #endif