From 21279c7ada1e47e8bfc6375f67768c8eedffb680 Mon Sep 17 00:00:00 2001 From: joshualitt Date: Mon, 11 May 2015 07:21:37 -0700 Subject: AADistanceFieldPathRenderer unit tests TBR=bsalomon@google.com BUG=skia: Review URL: https://codereview.chromium.org/1129083005 --- include/gpu/GrTestUtils.h | 2 + src/gpu/GrAADistanceFieldPathRenderer.cpp | 111 +++++++++++++++++++++++++----- src/gpu/GrAADistanceFieldPathRenderer.h | 4 +- src/gpu/GrOvalRenderer.cpp | 19 ++--- src/gpu/GrTestUtils.cpp | 15 ++++ 5 files changed, 120 insertions(+), 31 deletions(-) diff --git a/include/gpu/GrTestUtils.h b/include/gpu/GrTestUtils.h index 2109ad657b..21db543c04 100644 --- a/include/gpu/GrTestUtils.h +++ b/include/gpu/GrTestUtils.h @@ -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*); } diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp index 3d4a89b0c0..3e054d144a 100755 --- a/src/gpu/GrAADistanceFieldPathRenderer.cpp +++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp @@ -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 diff --git a/src/gpu/GrAADistanceFieldPathRenderer.h b/src/gpu/GrAADistanceFieldPathRenderer.h index 6cbee1f5c9..bb76eff252 100755 --- a/src/gpu/GrAADistanceFieldPathRenderer.h +++ b/src/gpu/GrAADistanceFieldPathRenderer.h @@ -72,16 +72,18 @@ private: static void HandleEviction(GrBatchAtlas::AtlasID, void*); + typedef SkTDynamicHash PathCache; typedef SkTInternalLList PathDataList; GrContext* fContext; GrBatchAtlas* fAtlas; - SkTDynamicHash fPathCache; + PathCache fPathCache; PathDataList fPathList; typedef GrPathRenderer INHERITED; friend class AADistanceFieldPathBatch; + friend struct PathTestStruct; }; #endif diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 886159cdac..ebac42fcac 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -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 diff --git a/src/gpu/GrTestUtils.cpp b/src/gpu/GrTestUtils.cpp index 0bb4044eaa..39f4834657 100644 --- a/src/gpu/GrTestUtils.cpp +++ b/src/gpu/GrTestUtils.cpp @@ -175,6 +175,21 @@ const SkPath& TestPath(SkRandom* random) { return gPath[random->nextULessThan(static_cast(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 -- cgit v1.2.3