#include "GrBatch.h"
#include "GrBatchTarget.h"
+#include "GrBatchTest.h"
#include "GrContext.h"
#include "GrPipelineBuilder.h"
#include "GrResourceProvider.h"
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,
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());
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
#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) {
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) {
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
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