bool prepareForOffscreenAA(GrDrawTarget* target,
bool requireStencil,
const GrIRect& boundRect,
+ GrPathRenderer* pr,
OffscreenRecord* record);
// sets up target to draw coverage to the supersampled render target
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
*/
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.
*/
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;
#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
bool GrContext::prepareForOffscreenAA(GrDrawTarget* target,
bool requireStencil,
const GrIRect& boundRect,
+ GrPathRenderer* pr,
OffscreenRecord* record) {
GrAssert(GR_USE_OFFSCREEN_AA);
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()) ?
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;
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;
}
}
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);
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);
#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) {
}
// 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.