Remove global curve subdivision tolerance from GrPathUtils.
authortomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 24 Jun 2011 15:53:40 +0000 (15:53 +0000)
committertomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 24 Jun 2011 15:53:40 +0000 (15:53 +0000)
Put in framework for changing curve subdivision tolerance when rendering
offscreen AA tiles; however, comment out actual tolerance changes because
of possible quality issues with simple circles (q.v. Arcs slide of SampleApp).

git-svn-id: http://skia.googlecode.com/svn/trunk@1702 2bbb7eff-a529-9590-31e7-b0007b416f81

gpu/include/GrContext.h
gpu/include/GrPathRenderer.h
gpu/src/GrContext.cpp
gpu/src/GrPathRenderer.cpp
gpu/src/GrPathUtils.cpp
gpu/src/GrPathUtils.h
gpu/src/GrTesselatedPathRenderer.cpp

index 8d482e9..0528267 100644 (file)
@@ -594,6 +594,7 @@ private:
     bool prepareForOffscreenAA(GrDrawTarget* target,
                                bool requireStencil,
                                const GrIRect& boundRect,
+                               GrPathRenderer* pr,
                                OffscreenRecord* record);
 
     // sets up target to draw coverage to the supersampled render target
@@ -611,7 +612,9 @@ private:
                             OffscreenRecord* record);
 
     // restored the draw target state and releases offscreen target to cache
-    void cleanupOffscreenAA(GrDrawTarget* target, OffscreenRecord* record);
+    void cleanupOffscreenAA(GrDrawTarget* target,
+                            GrPathRenderer* pr,
+                            OffscreenRecord* record);
     
     // computes vertex layout bits based on the paint. If paint expresses
     // a texture for a stage, the stage coords will be bound to postitions
index 1ebad4f..d77aad6 100644 (file)
@@ -27,6 +27,8 @@ struct GrPoint;
  */
 class GR_API GrPathRenderer : public GrRefCnt {
 public:
+    GrPathRenderer(void);
+
     /**
      * Returns true if this path renderer is able to render the path.
      * Returning false allows the caller to fallback to another path renderer.
@@ -122,6 +124,19 @@ public:
      */
     static GrPathRenderer* CreatePathRenderer();
 
+    /**
+     * Multiply curve tolerance by the given value, increasing or decreasing
+     * the maximum error permitted in tesselating curves with short straight
+     * line segments.
+     */
+    void scaleCurveTolerance(GrScalar multiplier) {
+        GrAssert(multiplier > 0);
+        fCurveTolerance = SkScalarMul(fCurveTolerance, multiplier);
+    }
+
+protected:
+    GrScalar fCurveTolerance;
+
 private:
 
     typedef GrRefCnt INHERITED;
index 56ebb68..a2b2a16 100644 (file)
@@ -24,6 +24,7 @@
 #include "GrInOrderDrawBuffer.h"
 #include "GrBufferAllocPool.h"
 #include "GrPathRenderer.h"
+#include "GrPathUtils.h"
 
 // Using MSAA seems to be slower for some yet unknown reason.
 #define PREFER_MSAA_OFFSCREEN_AA 0
@@ -577,6 +578,7 @@ bool GrContext::doOffscreenAA(GrDrawTarget* target,
 bool GrContext::prepareForOffscreenAA(GrDrawTarget* target,
                                       bool requireStencil,
                                       const GrIRect& boundRect,
+                                      GrPathRenderer* pr,
                                       OffscreenRecord* record) {
 
     GrAssert(GR_USE_OFFSCREEN_AA);
@@ -604,7 +606,7 @@ bool GrContext::prepareForOffscreenAA(GrDrawTarget* target,
 
     if (PREFER_MSAA_OFFSCREEN_AA && fGpu->supportsFullsceneAA()) {
         record->fDownsample = OffscreenRecord::kFSAA_Downsample;
-        record->fScale = GR_Scalar1;
+        record->fScale = 1;
         desc.fAALevel = kMed_GrAALevel;
     } else {
         record->fDownsample = (fGpu->supports4x4DownsampleFilter()) ?
@@ -615,7 +617,12 @@ bool GrContext::prepareForOffscreenAA(GrDrawTarget* target,
         GR_STATIC_ASSERT(4 == OFFSCREEN_SSAA_SCALE);
         desc.fAALevel = kNone_GrAALevel;
     }
-
+    // Avoid overtesselating paths in AA buffers; may unduly reduce quality
+    // of simple circles?
+    if (pr) {
+        //pr->scaleCurveTolerance(GrIntToScalar(record->fScale));
+    }
+    
     desc.fWidth *= record->fScale;
     desc.fHeight *= record->fScale;
 
@@ -798,9 +805,15 @@ void GrContext::doOffscreenAAPass2(GrDrawTarget* target,
     target->drawSimpleRect(dstRect, NULL, stages);
 }
 
-void GrContext::cleanupOffscreenAA(GrDrawTarget* target, OffscreenRecord* record) {
+void GrContext::cleanupOffscreenAA(GrDrawTarget* target,
+                                   GrPathRenderer* pr,
+                                   OffscreenRecord* record) {
     this->unlockTexture(record->fEntry0);
     record->fEntry0 = NULL;
+    if (pr) {
+        // Counterpart of scale() in prepareForOffscreenAA()
+        //pr->scaleCurveTolerance(SkScalarInvert(SkIntToScalar(record->fScale)));
+    }
     if (NULL != record->fEntry1) {
         this->unlockTexture(record->fEntry1);
         record->fEntry1 = NULL;
@@ -1337,7 +1350,8 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
             }
         }
         OffscreenRecord record;
-        if (this->prepareForOffscreenAA(target, needsStencil, bound, &record)) {
+        if (this->prepareForOffscreenAA(target, needsStencil, bound,
+                                        pr, &record)) {
             for (int tx = 0; tx < record.fTileCountX; ++tx) {
                 for (int ty = 0; ty < record.fTileCountY; ++ty) {
                     this->setupOffscreenAAPass1(target, bound, tx, ty, &record);
@@ -1345,7 +1359,7 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
                     this->doOffscreenAAPass2(target, paint, bound, tx, ty, &record);
                 }
             }
-            this->cleanupOffscreenAA(target, &record);
+            this->cleanupOffscreenAA(target, pr, &record);
             if (IsFillInverted(fill) && bound != clipIBounds) {
                 int stageMask = paint.getActiveStageMask();
                 GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask);
index 58bb12e..1795bd4 100644 (file)
@@ -6,10 +6,15 @@
 #include "GrMemory.h"
 #include "GrTexture.h"
 
+GrPathRenderer::GrPathRenderer()
+    : fCurveTolerance (GR_Scalar1) {
+
+}
+   
 GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport,
                                              bool stencilWrapOpsSupport)
-    : fSeparateStencil(separateStencilSupport),
-      fStencilWrapOps(stencilWrapOpsSupport) {
+    : fSeparateStencil(separateStencilSupport)
+    , fStencilWrapOps(stencilWrapOpsSupport) {
 
 }
 
@@ -197,7 +202,7 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target,
     // stretch when mapping to screen coordinates.
     GrScalar stretch = viewM.getMaxStretch();
     bool useStretch = stretch > 0;
-    GrScalar tol = GrPathUtils::gTolerance;
+    GrScalar tol = fCurveTolerance;
 
     if (!useStretch) {
         // TODO: deal with perspective in some better way.
index aebdf1d..e7c404c 100644 (file)
@@ -17,8 +17,6 @@
 #include "GrPathUtils.h"
 #include "GrPoint.h"
 
-const GrScalar GrPathUtils::gTolerance = GR_Scalar1;
-
 static const int MAX_POINTS_PER_CURVE = 1 << 10;
 
 uint32_t GrPathUtils::quadraticPointCount(const GrPoint points[],
index 2cd00cb..9755db6 100644 (file)
@@ -44,7 +44,5 @@ public:
                                         GrScalar tolSqd,
                                         GrPoint** points,
                                         uint32_t pointsLeft);
-
-    static const GrScalar gTolerance;
 };
 #endif
index 2783a9b..c1d5ac0 100644 (file)
@@ -365,7 +365,7 @@ void GrTesselatedPathRenderer::drawPath(GrDrawTarget* target,
     // stretch when mapping to screen coordinates.
     GrScalar stretch = viewM.getMaxStretch();
     bool useStretch = stretch > 0;
-    GrScalar tol = GrPathUtils::gTolerance;
+    GrScalar tol = fCurveTolerance;
 
     if (!useStretch) {
         // TODO: deal with perspective in some better way.