Remove global curve subdivision tolerance from GrPathUtils.
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
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 8d482e9..0528267 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -594,6 +594,7 @@
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 @@
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
diff --git a/gpu/include/GrPathRenderer.h b/gpu/include/GrPathRenderer.h
index 1ebad4f..d77aad6 100644
--- a/gpu/include/GrPathRenderer.h
+++ b/gpu/include/GrPathRenderer.h
@@ -27,6 +27,8 @@
*/
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 @@
*/
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;
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index 56ebb68..a2b2a16 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -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::prepareForOffscreenAA(GrDrawTarget* target,
bool requireStencil,
const GrIRect& boundRect,
+ GrPathRenderer* pr,
OffscreenRecord* record) {
GrAssert(GR_USE_OFFSCREEN_AA);
@@ -604,7 +606,7 @@
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 @@
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 @@
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 @@
}
}
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 @@
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);
diff --git a/gpu/src/GrPathRenderer.cpp b/gpu/src/GrPathRenderer.cpp
index 58bb12e..1795bd4 100644
--- a/gpu/src/GrPathRenderer.cpp
+++ b/gpu/src/GrPathRenderer.cpp
@@ -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 @@
// 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.
diff --git a/gpu/src/GrPathUtils.cpp b/gpu/src/GrPathUtils.cpp
index aebdf1d..e7c404c 100644
--- a/gpu/src/GrPathUtils.cpp
+++ b/gpu/src/GrPathUtils.cpp
@@ -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[],
diff --git a/gpu/src/GrPathUtils.h b/gpu/src/GrPathUtils.h
index 2cd00cb..9755db6 100644
--- a/gpu/src/GrPathUtils.h
+++ b/gpu/src/GrPathUtils.h
@@ -44,7 +44,5 @@
GrScalar tolSqd,
GrPoint** points,
uint32_t pointsLeft);
-
- static const GrScalar gTolerance;
};
#endif
diff --git a/gpu/src/GrTesselatedPathRenderer.cpp b/gpu/src/GrTesselatedPathRenderer.cpp
index 2783a9b..c1d5ac0 100644
--- a/gpu/src/GrTesselatedPathRenderer.cpp
+++ b/gpu/src/GrTesselatedPathRenderer.cpp
@@ -365,7 +365,7 @@
// 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.