Index: src/gpu/GrAADistanceFieldPathRenderer.cpp |
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp |
index 7c0468d933704ff325a438e1f0e8a7a70def617f..7c061af58283570cc9577f230982be5fb68799bb 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 "GrBufferAllocPool.h" |
#include "GrContext.h" |
#include "GrPipelineBuilder.h" |
@@ -557,6 +558,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, |
@@ -572,24 +595,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()); |
@@ -603,3 +613,75 @@ 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; |
robertphillips
2015/05/07 19:30:24
PathTestStruct() : fContextID(0), fAtlas(NULL) {}
joshualitt
2015/05/07 21:22:38
Acknowledged.
|
+ ~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; |
robertphillips
2015/05/07 19:30:24
Just PathCache as the type ?
joshualitt
2015/05/07 21:22:38
Acknowledged.
|
+ GrAADistanceFieldPathRenderer::PathCache fPathCache; |
+ PathDataList fPathList; |
+}; |
+ |
+BATCH_TEST_DEFINE(AADistanceFieldPathRenderer) { |
+ static bool gInit; |
+ static PathTestStruct gTestStruct; |
+ |
robertphillips
2015/05/07 19:30:24
Would initializing fContextID to zero allow us to
joshualitt
2015/05/07 21:22:38
Acknowledged.
|
+ if(!gInit || context->uniqueID() != gTestStruct.fContextID) { |
+ gInit = true; |
+ 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 |