Use a prioritized list of path renderers in Gr.

http://codereview.appspot.com/4867058



git-svn-id: http://skia.googlecode.com/svn/trunk@2143 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index b3e902d..506cb9f 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -61,11 +61,11 @@
     delete fDrawBuffer;
     delete fDrawBufferVBAllocPool;
     delete fDrawBufferIBAllocPool;
-    GrSafeUnref(fDefaultPathRenderer);
-    GrSafeUnref(fCustomPathRenderer);
+
     GrSafeUnref(fAAFillRectIndexBuffer);
     GrSafeUnref(fAAStrokeRectIndexBuffer);
     fGpu->unref();
+    GrSafeUnref(fPathRendererChain);
 }
 
 void GrContext::contextLost() {
@@ -78,6 +78,10 @@
     // don't try to free the resources in the API.
     fGpu->abandonResources();
 
+    // a path renderer may be holding onto resources that
+    // are now unusable
+    GrSafeSetNull(fPathRendererChain);
+
     delete fDrawBuffer;
     fDrawBuffer = NULL;
 
@@ -103,6 +107,8 @@
     this->flush();
     fTextureCache->removeAll();
     fFontCache->freeAll();
+    // a path renderer may be holding onto resources
+    GrSafeSetNull(fPathRendererChain);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1411,7 +1417,12 @@
                          GrPathFill fill, const GrPoint* translate) {
 
     GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
-    GrPathRenderer* pr = this->getPathRenderer(path, fill);
+    GrPathRenderer* pr = this->getPathRenderer(target, path, fill);
+    if (NULL == pr) {
+        GrPrintf("Unable to find path renderer compatible with path.\n");
+        return;
+    }
+
     GrPathRenderer::AutoClearPath arp(pr, target, &path, fill, translate);
     GrDrawTarget::StageBitfield stageMask = paint.getActiveStageMask();
 
@@ -1658,6 +1669,16 @@
     return target;
 }
 
+GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
+                                           const GrPath& path,
+                                           GrPathFill fill) {
+    if (NULL == fPathRendererChain) {
+        fPathRendererChain = 
+            new GrPathRendererChain(this, GrPathRendererChain::kNone_UsageFlag);
+    }
+    return fPathRendererChain->getPathRenderer(target, path, fill);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrContext::setRenderTarget(GrRenderTarget* target) {
@@ -1712,11 +1733,7 @@
     fGpu->ref();
     fGpu->setContext(this);
 
-    fDefaultPathRenderer = 
-        new GrDefaultPathRenderer(gpu->supportsTwoSidedStencil(),
-                                  gpu->supportsStencilWrapOps());
-    fCustomPathRenderer = GrPathRenderer::CreatePathRenderer();
-    fGpu->setClipPathRenderer(fCustomPathRenderer);
+    fPathRendererChain = NULL;
 
     fTextureCache = new GrResourceCache(MAX_TEXTURE_CACHE_COUNT,
                                         MAX_TEXTURE_CACHE_BYTES);
@@ -1780,17 +1797,6 @@
     return fGpu->getQuadIndexBuffer();
 }
 
-GrPathRenderer* GrContext::getPathRenderer(const GrPath& path,
-                                           GrPathFill fill) {
-    if (NULL != fCustomPathRenderer &&
-        fCustomPathRenderer->canDrawPath(path, fill)) {
-        return fCustomPathRenderer;
-    } else {
-        GrAssert(fDefaultPathRenderer->canDrawPath(path, fill));
-        return fDefaultPathRenderer;
-    }
-}
-
 void GrContext::convolveInX(GrTexture* texture,
                             const SkRect& rect,
                             const float* kernel,