Chromium Code Reviews| 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 |