Index: src/gpu/GrAADistanceFieldPathRenderer.cpp |
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp |
index 3d4a89b0c013b8b4c0d72f4bd2dd1d8ad37a67a9..3e054d144ae98ccde4d7e0c79c00834e5468bbbd 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 |