diff options
author | joshualitt <joshualitt@chromium.org> | 2014-10-31 13:56:50 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-31 13:56:50 -0700 |
commit | 92e496f96abbd664888f0c8a7d546ab02e703bf7 (patch) | |
tree | a9396fed2f759f748efe086fd76eee6f7bc6c762 /src | |
parent | 2faa2284357d7cec51b26d8251c53bc91251b1fe (diff) |
Beginning to refactor nvpr code
BUG=skia:
Review URL: https://codereview.chromium.org/687563008
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 55 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 21 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 79 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 9 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.h | 20 | ||||
-rw-r--r-- | src/gpu/GrPathRendering.h | 20 | ||||
-rw-r--r-- | src/gpu/GrStencilAndCoverPathRenderer.cpp | 53 | ||||
-rw-r--r-- | src/gpu/GrStencilAndCoverTextContext.cpp | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathRendering.cpp | 141 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathRendering.h | 8 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 6 |
12 files changed, 209 insertions, 213 deletions
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 11abb57691..2f25272e31 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -527,28 +527,20 @@ void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, } } -void GrDrawTarget::stencilPath(const GrPath* path, SkPath::FillType fill) { +void GrDrawTarget::stencilPath(const GrPath* path, GrPathRendering::FillType fill) { // TODO: extract portions of checkDraw that are relevant to path stenciling. SkASSERT(path); SkASSERT(this->caps()->pathRenderingSupport()); - SkASSERT(!SkPath::IsInverseFillType(fill)); this->onStencilPath(path, fill); } -void GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) { +void GrDrawTarget::drawPath(const GrPath* path, GrPathRendering::FillType fill) { // TODO: extract portions of checkDraw that are relevant to path rendering. SkASSERT(path); SkASSERT(this->caps()->pathRenderingSupport()); - const GrDrawState* drawState = &getDrawState(); - SkRect devBounds; - if (SkPath::IsInverseFillType(fill)) { - devBounds = SkRect::MakeWH(SkIntToScalar(drawState->getRenderTarget()->width()), - SkIntToScalar(drawState->getRenderTarget()->height())); - } else { - devBounds = path->getBounds(); - } - SkMatrix viewM = drawState->getViewMatrix(); + SkRect devBounds = path->getBounds(); + SkMatrix viewM = this->drawState()->getViewMatrix(); viewM.mapRect(&devBounds); GrDeviceCoordTexture dstCopy; @@ -562,7 +554,7 @@ void GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) { void GrDrawTarget::drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count, const float transforms[], PathTransformType transformsType, - SkPath::FillType fill) { + GrPathRendering::FillType fill) { SkASSERT(this->caps()->pathRenderingSupport()); SkASSERT(pathRange); SkASSERT(indices); @@ -724,43 +716,6 @@ void GrDrawTarget::onDrawRect(const SkRect& rect, void GrDrawTarget::clipWillBeSet(const GrClipData* clipData) { } -static const GrStencilSettings& winding_path_stencil_settings() { - GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, - kIncClamp_StencilOp, - kIncClamp_StencilOp, - kAlwaysIfInClip_StencilFunc, - 0xFFFF, 0xFFFF, 0xFFFF); - return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); -} - -static const GrStencilSettings& even_odd_path_stencil_settings() { - GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, - kInvert_StencilOp, - kInvert_StencilOp, - kAlwaysIfInClip_StencilFunc, - 0xFFFF, 0xFFFF, 0xFFFF); - return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); -} - -void GrDrawTarget::getPathStencilSettingsForFillType(SkPath::FillType fill, - GrStencilSettings* outStencilSettings) { - - switch (fill) { - default: - SkFAIL("Unexpected path fill."); - /* fallthrough */; - case SkPath::kWinding_FillType: - case SkPath::kInverseWinding_FillType: - *outStencilSettings = winding_path_stencil_settings(); - break; - case SkPath::kEvenOdd_FillType: - case SkPath::kInverseEvenOdd_FillType: - *outStencilSettings = even_odd_path_stencil_settings(); - break; - } - this->getClipMaskManager()->adjustPathStencilParams(outStencilSettings); -} - //////////////////////////////////////////////////////////////////////////////// GrDrawTarget::AutoStateRestore::AutoStateRestore() { diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 7d8a03ce71..4545f74d25 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -315,15 +315,16 @@ public: /** * Draws path into the stencil buffer. The fill must be either even/odd or * winding (not inverse or hairline). It will respect the HW antialias flag - * on the draw state (if possible in the 3D API). + * on the draw state (if possible in the 3D API). Note, we will never have an inverse fill + * with stencil path */ - void stencilPath(const GrPath*, SkPath::FillType fill); + void stencilPath(const GrPath*, GrPathRendering::FillType fill); /** * Draws a path. Fill must not be a hairline. It will respect the HW * antialias flag on the draw state (if possible in the 3D API). */ - void drawPath(const GrPath*, SkPath::FillType fill); + void drawPath(const GrPath*, GrPathRendering::FillType fill); /** * Draws many paths. It will respect the HW @@ -340,7 +341,7 @@ public: void drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count, const float transforms[], PathTransformType transformsType, - SkPath::FillType fill); + GrPathRendering::FillType fill); /** * Helper function for drawing rects. It performs a geometry src push and pop @@ -490,7 +491,7 @@ public: /** * For subclass internal use to invoke a call to onDrawPath(). */ - void executeDrawPath(const GrPath* path, SkPath::FillType fill, + void executeDrawPath(const GrPath* path, GrPathRendering::FillType fill, const GrDeviceCoordTexture* dstCopy) { this->onDrawPath(path, fill, dstCopy); } @@ -501,13 +502,11 @@ public: void executeDrawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count, const float transforms[], PathTransformType transformsType, - SkPath::FillType fill, + GrPathRendering::FillType fill, const GrDeviceCoordTexture* dstCopy) { this->onDrawPaths(pathRange, indices, count, transforms, transformsType, fill, dstCopy); } - void getPathStencilSettingsForFillType(SkPath::FillType, GrStencilSettings*); - //////////////////////////////////////////////////////////////////////////// /** @@ -898,13 +897,13 @@ private: const SkRect* localRect, const SkMatrix* localMatrix); - virtual void onStencilPath(const GrPath*, SkPath::FillType) = 0; - virtual void onDrawPath(const GrPath*, SkPath::FillType, + virtual void onStencilPath(const GrPath*, GrPathRendering::FillType) = 0; + virtual void onDrawPath(const GrPath*, GrPathRendering::FillType, const GrDeviceCoordTexture* dstCopy) = 0; virtual void onDrawPaths(const GrPathRange*, const uint32_t indices[], int count, const float transforms[], PathTransformType, - SkPath::FillType, const GrDeviceCoordTexture*) = 0; + GrPathRendering::FillType, const GrDeviceCoordTexture*) = 0; virtual void didAddGpuTraceMarker() = 0; virtual void didRemoveGpuTraceMarker() = 0; diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 4b1c35ad4e..2f4f0a68c8 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -275,13 +275,13 @@ const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const { bool GrGpu::setupClipAndFlushState(DrawType type, const GrDeviceCoordTexture* dstCopy, const SkRect* devBounds, - GrDrawState::AutoRestoreEffects* are) { + GrDrawState::AutoRestoreEffects* are, + GrDrawState::AutoRestoreStencil* ars) { GrClipMaskManager::ScissorState scissorState; - GrDrawState::AutoRestoreStencil ars; if (!fClipMaskManager.setupClipping(this->getClip(), devBounds, are, - &ars, + ars, &scissorState)) { return false; } @@ -325,56 +325,109 @@ void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) { void GrGpu::onDraw(const DrawInfo& info) { this->handleDirtyContext(); GrDrawState::AutoRestoreEffects are; + GrDrawState::AutoRestoreStencil ars; if (!this->setupClipAndFlushState(PrimTypeToDrawType(info.primitiveType()), info.getDstCopy(), info.getDevBounds(), - &are)) { + &are, + &ars)) { return; } this->onGpuDraw(info); } -void GrGpu::onStencilPath(const GrPath* path, SkPath::FillType fill) { + +// TODO hack +static const GrStencilSettings& winding_path_stencil_settings() { + GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, + kIncClamp_StencilOp, + kIncClamp_StencilOp, + kAlwaysIfInClip_StencilFunc, + 0xFFFF, 0xFFFF, 0xFFFF); + return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); +} + +static const GrStencilSettings& even_odd_path_stencil_settings() { + GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, + kInvert_StencilOp, + kInvert_StencilOp, + kAlwaysIfInClip_StencilFunc, + 0xFFFF, 0xFFFF, 0xFFFF); + return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); +} + +static void get_path_stencil_settings_for_filltype(GrPathRendering::FillType fill, + GrStencilSettings* outStencilSettings) { + + switch (fill) { + default: + SkFAIL("Unexpected path fill."); + case GrPathRendering::kWinding_FillType: + *outStencilSettings = winding_path_stencil_settings(); + break; + case GrPathRendering::kEvenOdd_FillType: + *outStencilSettings = even_odd_path_stencil_settings(); + break; + } +} + +void GrGpu::onStencilPath(const GrPath* path, GrPathRendering::FillType fill) { this->handleDirtyContext(); GrDrawState::AutoRestoreEffects are; - if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, NULL, &are)) { + GrDrawState::AutoRestoreStencil ars; + if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, NULL, &are, &ars)) { return; } - this->pathRendering()->stencilPath(path, fill); + GrStencilSettings stencilSettings; + get_path_stencil_settings_for_filltype(fill, &stencilSettings); + fClipMaskManager.adjustPathStencilParams(&stencilSettings); + + this->pathRendering()->stencilPath(path, stencilSettings); } -void GrGpu::onDrawPath(const GrPath* path, SkPath::FillType fill, +void GrGpu::onDrawPath(const GrPath* path, GrPathRendering::FillType fill, const GrDeviceCoordTexture* dstCopy) { this->handleDirtyContext(); drawState()->setDefaultVertexAttribs(); GrDrawState::AutoRestoreEffects are; - if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, NULL, &are)) { + GrDrawState::AutoRestoreStencil ars; + if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, NULL, &are, &ars)) { return; } - this->pathRendering()->drawPath(path, fill); + GrStencilSettings stencilSettings; + get_path_stencil_settings_for_filltype(fill, &stencilSettings); + fClipMaskManager.adjustPathStencilParams(&stencilSettings); + + this->pathRendering()->drawPath(path, stencilSettings); } void GrGpu::onDrawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count, const float transforms[], PathTransformType transformsType, - SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) { + GrPathRendering::FillType fill, const GrDeviceCoordTexture* dstCopy) { this->handleDirtyContext(); drawState()->setDefaultVertexAttribs(); GrDrawState::AutoRestoreEffects are; - if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, NULL, &are)) { + GrDrawState::AutoRestoreStencil ars; + if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, NULL, &are, &ars)) { return; } + GrStencilSettings stencilSettings; + get_path_stencil_settings_for_filltype(fill, &stencilSettings); + fClipMaskManager.adjustPathStencilParams(&stencilSettings); + pathRange->willDrawPaths(indices, count); - this->pathRendering()->drawPaths(pathRange, indices, count, transforms, transformsType, fill); + this->pathRendering()->drawPaths(pathRange, indices, count, transforms, transformsType, + stencilSettings); } void GrGpu::finalizeReservedVertices() { diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 7c90ee4702..0e2ec88b8c 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -335,7 +335,8 @@ protected: bool setupClipAndFlushState(DrawType, const GrDeviceCoordTexture* dstCopy, const SkRect* devBounds, - GrDrawState::AutoRestoreEffects*); + GrDrawState::AutoRestoreEffects*, + GrDrawState::AutoRestoreStencil*); // Functions used to map clip-respecting stencil tests into normal // stencil funcs supported by GPUs. @@ -452,13 +453,13 @@ private: // GrDrawTarget overrides virtual void onDraw(const DrawInfo&) SK_OVERRIDE; - virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; - virtual void onDrawPath(const GrPath*, SkPath::FillType, + virtual void onStencilPath(const GrPath*, GrPathRendering::FillType) SK_OVERRIDE; + virtual void onDrawPath(const GrPath*, GrPathRendering::FillType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; virtual void onDrawPaths(const GrPathRange*, const uint32_t indices[], int count, const float transforms[], PathTransformType, - SkPath::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE; + GrPathRendering::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE; // readies the pools to provide vertex/index data. void prepareVertexPool(); diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index e7d0f8377d..61c3e0c21d 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -361,7 +361,7 @@ void GrInOrderDrawBuffer::onDraw(const DrawInfo& info) { } } -void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fill) { +void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathRendering::FillType fill) { this->recordClipIfNecessary(); // Only compare the subset of GrDrawState relevant to path stenciling? this->recordStateIfNecessary(); @@ -371,7 +371,8 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil } void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, - SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) { + GrPathRendering::FillType fill, + const GrDeviceCoordTexture* dstCopy) { this->recordClipIfNecessary(); // TODO: Only compare the subset of GrDrawState relevant to path covering? this->recordStateIfNecessary(); @@ -386,7 +387,8 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count, const float transforms[], PathTransformType transformsType, - SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) { + GrPathRendering::FillType fill, + const GrDeviceCoordTexture* dstCopy) { SkASSERT(pathRange); SkASSERT(indices); SkASSERT(transforms); diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index 7b9a926cf4..e6971a9e47 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -139,7 +139,7 @@ private: virtual void execute(GrClipTarget*); - SkPath::FillType fFill; + GrPathRendering::FillType fFill; private: GrPendingIOResource<const GrPath, kRead_GrIOType> fPath; @@ -152,8 +152,8 @@ private: virtual void execute(GrClipTarget*); - SkPath::FillType fFill; - GrDeviceCoordTexture fDstCopy; + GrPathRendering::FillType fFill; + GrDeviceCoordTexture fDstCopy; private: GrPendingIOResource<const GrPath, kRead_GrIOType> fPath; @@ -168,10 +168,10 @@ private: virtual void execute(GrClipTarget*); - size_t fCount; - PathTransformType fTransformsType; - SkPath::FillType fFill; - GrDeviceCoordTexture fDstCopy; + size_t fCount; + PathTransformType fTransformsType; + GrPathRendering::FillType fFill; + GrDeviceCoordTexture fDstCopy; private: GrPendingIOResource<const GrPathRange, kRead_GrIOType> fPathRange; @@ -257,13 +257,13 @@ private: const SkRect* localRect, const SkMatrix* localMatrix) SK_OVERRIDE; - virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; - virtual void onDrawPath(const GrPath*, SkPath::FillType, + virtual void onStencilPath(const GrPath*, GrPathRendering::FillType) SK_OVERRIDE; + virtual void onDrawPath(const GrPath*, GrPathRendering::FillType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; virtual void onDrawPaths(const GrPathRange*, const uint32_t indices[], int count, const float transforms[], PathTransformType, - SkPath::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE; + GrPathRendering::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE; virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, diff --git a/src/gpu/GrPathRendering.h b/src/gpu/GrPathRendering.h index 26cfa110ce..cd42206f43 100644 --- a/src/gpu/GrPathRendering.h +++ b/src/gpu/GrPathRendering.h @@ -16,6 +16,7 @@ class SkDescriptor; class SkTypeface; class GrPath; class GrGpu; +class GrStencilSettings; /** * Abstract class wrapping HW path rendering API. @@ -33,6 +34,18 @@ class GrPathRendering { public: virtual ~GrPathRendering() { } + // No native support for inverse at this time + enum FillType { + /** Specifies that "inside" is computed by a non-zero sum of signed + edge crossings + */ + kWinding_FillType, + /** Specifies that "inside" is computed by an odd number of edge + crossings + */ + kEvenOdd_FillType, + }; + enum PathTransformType { kNone_PathTransformType, //!< [] kTranslateX_PathTransformType, //!< [kMTransX] @@ -111,10 +124,11 @@ public: */ virtual GrPathRange* createGlyphs(const SkTypeface*, const SkDescriptor*, const SkStrokeRec&) = 0; - virtual void stencilPath(const GrPath*, SkPath::FillType) = 0; - virtual void drawPath(const GrPath*, SkPath::FillType) = 0; + virtual void stencilPath(const GrPath*, const GrStencilSettings&) = 0; + virtual void drawPath(const GrPath*, const GrStencilSettings&) = 0; virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count, - const float transforms[], PathTransformType, SkPath::FillType) = 0; + const float transforms[], PathTransformType, + const GrStencilSettings&) = 0; protected: GrPathRendering() { } diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp index 5f55c1a214..6ed4b9e61c 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp @@ -14,6 +14,22 @@ #include "GrPath.h" #include "SkStrokeRec.h" +/* + * For now paths only natively support winding and even odd fill types + */ +static GrPathRendering::FillType convert_skpath_filltype(SkPath::FillType fill) { + switch (fill) { + default: + SkFAIL("Incomplete Switch\n"); + case SkPath::kWinding_FillType: + case SkPath::kInverseWinding_FillType: + return GrPathRendering::kWinding_FillType; + case SkPath::kEvenOdd_FillType: + case SkPath::kInverseEvenOdd_FillType: + return GrPathRendering::kEvenOdd_FillType; + } +} + GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrContext* context) { SkASSERT(context); SkASSERT(context->getGpu()); @@ -44,10 +60,10 @@ bool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path, target->getDrawState().getStencil().isDisabled(); } -GrPathRenderer::StencilSupport GrStencilAndCoverPathRenderer::onGetStencilSupport( - const SkPath&, - const SkStrokeRec& , - const GrDrawTarget*) const { +GrPathRenderer::StencilSupport +GrStencilAndCoverPathRenderer::onGetStencilSupport(const SkPath&, + const SkStrokeRec& , + const GrDrawTarget*) const { return GrPathRenderer::kStencilOnly_StencilSupport; } @@ -67,7 +83,7 @@ void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path, GrDrawTarget* target) { SkASSERT(!path.isInverseFillType()); SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke)); - target->stencilPath(p, path.getFillType()); + target->stencilPath(p, convert_skpath_filltype(path.getFillType())); } bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, @@ -94,7 +110,27 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, 0x0000, 0xffff); - *drawState->stencil() = kInvertedStencilPass; + drawState->setStencil(kInvertedStencilPass); + + // fake inverse with a stencil and cover + target->stencilPath(p, convert_skpath_filltype(path.getFillType())); + + GrDrawState::AutoViewMatrixRestore avmr; + SkRect bounds = SkRect::MakeLTRB(0, 0, + SkIntToScalar(drawState->getRenderTarget()->width()), + SkIntToScalar(drawState->getRenderTarget()->height())); + SkMatrix vmi; + // mapRect through persp matrix may not be correct + if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) { + vmi.mapRect(&bounds); + // theoretically could set bloat = 0, instead leave it because of matrix inversion + // precision. + SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf; + bounds.outset(bloat, bloat); + } else { + avmr.setIdentity(drawState); + } + target->drawSimpleRect(bounds); } else { GR_STATIC_CONST_SAME_STENCIL(kStencilPass, kZero_StencilOp, @@ -104,11 +140,10 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, 0x0000, 0xffff); - *drawState->stencil() = kStencilPass; + drawState->setStencil(kStencilPass); + target->drawPath(p, convert_skpath_filltype(path.getFillType())); } - target->drawPath(p, path.getFillType()); - target->drawState()->stencil()->setDisabled(); return true; } diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp index b53ff797fa..94a6c2e528 100644 --- a/src/gpu/GrStencilAndCoverTextContext.cpp +++ b/src/gpu/GrStencilAndCoverTextContext.cpp @@ -413,7 +413,7 @@ void GrStencilAndCoverTextContext::flush() { } fDrawTarget->drawPaths(fGlyphs, fIndexBuffer, fPendingGlyphCount, - fTransformBuffer, fTransformType, SkPath::kWinding_FillType); + fTransformBuffer, fTransformType, GrPathRendering::kWinding_FillType); fPendingGlyphCount = 0; } diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp index 26584bc808..66b129e876 100644 --- a/src/gpu/gl/GrGLPathRendering.cpp +++ b/src/gpu/gl/GrGLPathRendering.cpp @@ -152,147 +152,88 @@ GrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface, return SkNEW_ARGS(GrGLPathRange, (fGpu, basePathID, numPaths, gpuMemorySize, stroke)); } -void GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) { +void GrGLPathRendering::stencilPath(const GrPath* path, const GrStencilSettings& stencilSettings) { GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); SkASSERT(fGpu->drawState()->getRenderTarget()); SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer()); - this->flushPathStencilSettings(fill); + this->flushPathStencilSettings(stencilSettings); SkASSERT(!fHWPathStencilSettings.isTwoSided()); + const SkStrokeRec& stroke = path->getStroke(); + GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); - GL_CALL(StencilFillPath(id, fillMode, writeMask)); + + if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { + GL_CALL(StencilFillPath(id, fillMode, writeMask)); + } + if (stroke.needToApply()) { + GL_CALL(StencilStrokePath(id, 0xffff, writeMask)); + } } -void GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) { +void GrGLPathRendering::drawPath(const GrPath* path, const GrStencilSettings& stencilSettings) { GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); SkASSERT(fGpu->drawState()->getRenderTarget()); SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer()); - this->flushPathStencilSettings(fill); + this->flushPathStencilSettings(stencilSettings); SkASSERT(!fHWPathStencilSettings.isTwoSided()); const SkStrokeRec& stroke = path->getStroke(); - SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill); - GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); - if (nonInvertedFill == fill) { - if (stroke.needToApply()) { - if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { - GL_CALL(StencilFillPath(id, fillMode, writeMask)); - } - this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDING_BOX); - } else { - this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDING_BOX); - } - } else { - if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { + if (stroke.needToApply()) { + if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { GL_CALL(StencilFillPath(id, fillMode, writeMask)); } - if (stroke.needToApply()) { - GL_CALL(StencilStrokePath(id, 0xffff, writeMask)); - } - - GrDrawState* drawState = fGpu->drawState(); - GrDrawState::AutoViewMatrixRestore avmr; - SkRect bounds = SkRect::MakeLTRB(0, 0, - SkIntToScalar(drawState->getRenderTarget()->width()), - SkIntToScalar(drawState->getRenderTarget()->height())); - SkMatrix vmi; - // mapRect through persp matrix may not be correct - if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) { - vmi.mapRect(&bounds); - // theoretically could set bloat = 0, instead leave it because of matrix inversion - // precision. - SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf; - bounds.outset(bloat, bloat); - } else { - avmr.setIdentity(drawState); - } - - fGpu->drawSimpleRect(bounds); + this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDING_BOX); + } else { + this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDING_BOX); } } void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count, const float transforms[], PathTransformType transformsType, - SkPath::FillType fill) { + const GrStencilSettings& stencilSettings) { SkASSERT(fGpu->caps()->pathRenderingSupport()); SkASSERT(fGpu->drawState()->getRenderTarget()); SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer()); GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID(); - this->flushPathStencilSettings(fill); + this->flushPathStencilSettings(stencilSettings); SkASSERT(!fHWPathStencilSettings.isTwoSided()); const SkStrokeRec& stroke = pathRange->getStroke(); - SkPath::FillType nonInvertedFill = - SkPath::ConvertToNonInverseFillType(fill); - GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode( fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); - if (nonInvertedFill == fill) { - if (stroke.needToApply()) { - if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { - GL_CALL(StencilFillPathInstanced( - count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, - writeMask, gXformType2GLType[transformsType], - transforms)); - } - this->stencilThenCoverStrokePathInstanced( - count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask, - GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, - gXformType2GLType[transformsType], transforms); - } else { - this->stencilThenCoverFillPathInstanced( - count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask, - GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, - gXformType2GLType[transformsType], transforms); - } - } else { - if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { + if (stroke.needToApply()) { + if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { GL_CALL(StencilFillPathInstanced( - count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, - writeMask, gXformType2GLType[transformsType], - transforms)); + count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, + writeMask, gXformType2GLType[transformsType], + transforms)); } - if (stroke.needToApply()) { - GL_CALL(StencilStrokePathInstanced( - count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, - writeMask, gXformType2GLType[transformsType], - transforms)); - } - - GrDrawState* drawState = fGpu->drawState(); - GrDrawState::AutoViewMatrixRestore avmr; - SkRect bounds = SkRect::MakeLTRB(0, 0, - SkIntToScalar(drawState->getRenderTarget()->width()), - SkIntToScalar(drawState->getRenderTarget()->height())); - SkMatrix vmi; - // mapRect through persp matrix may not be correct - if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) { - vmi.mapRect(&bounds); - // theoretically could set bloat = 0, instead leave it because of matrix inversion - // precision. - SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf; - bounds.outset(bloat, bloat); - } else { - avmr.setIdentity(drawState); - } - - fGpu->drawSimpleRect(bounds); + this->stencilThenCoverStrokePathInstanced( + count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask, + GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, + gXformType2GLType[transformsType], transforms); + } else { + this->stencilThenCoverFillPathInstanced( + count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask, + GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, + gXformType2GLType[transformsType], transforms); } } @@ -466,18 +407,16 @@ void GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) { fPathNameAllocator->free(path); } -void GrGLPathRendering::flushPathStencilSettings(SkPath::FillType fill) { - GrStencilSettings pathStencilSettings; - fGpu->getPathStencilSettingsForFillType(fill, &pathStencilSettings); - if (fHWPathStencilSettings != pathStencilSettings) { +void GrGLPathRendering::flushPathStencilSettings(const GrStencilSettings& stencilSettings) { + if (fHWPathStencilSettings != stencilSettings) { // Just the func, ref, and mask is set here. The op and write mask are params to the call // that draws the path to the SB (glStencilFillPath) GrGLenum func = - GrToGLStencilFunc(pathStencilSettings.func(GrStencilSettings::kFront_Face)); - GL_CALL(PathStencilFunc(func, pathStencilSettings.funcRef(GrStencilSettings::kFront_Face), - pathStencilSettings.funcMask(GrStencilSettings::kFront_Face))); + GrToGLStencilFunc(stencilSettings.func(GrStencilSettings::kFront_Face)); + GL_CALL(PathStencilFunc(func, stencilSettings.funcRef(GrStencilSettings::kFront_Face), + stencilSettings.funcMask(GrStencilSettings::kFront_Face))); - fHWPathStencilSettings = pathStencilSettings; + fHWPathStencilSettings = stencilSettings; } } diff --git a/src/gpu/gl/GrGLPathRendering.h b/src/gpu/gl/GrGLPathRendering.h index 5133506a42..f314563688 100644 --- a/src/gpu/gl/GrGLPathRendering.h +++ b/src/gpu/gl/GrGLPathRendering.h @@ -39,11 +39,11 @@ public: virtual GrPathRange* createGlyphs(const SkTypeface*, const SkDescriptor*, const SkStrokeRec&) SK_OVERRIDE; - virtual void stencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; - virtual void drawPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; + virtual void stencilPath(const GrPath*, const GrStencilSettings&) SK_OVERRIDE; + virtual void drawPath(const GrPath*, const GrStencilSettings&) SK_OVERRIDE; virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count, const float transforms[], PathTransformType, - SkPath::FillType) SK_OVERRIDE; + const GrStencilSettings&) SK_OVERRIDE; /* Called when the 3D context state is unknown. */ void resetContext(); @@ -107,7 +107,7 @@ private: }; const Caps& caps() const { return fCaps; } - void flushPathStencilSettings(SkPath::FillType fill); + void flushPathStencilSettings(const GrStencilSettings&); // NV_path_rendering v1.2 void stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index a00333ddab..9d08f641eb 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -1871,6 +1871,7 @@ void set_gl_stencil(const GrGLInterface* gl, } void GrGpuGL::flushStencil(const GrStencilSettings& stencilSettings, DrawType type) { + // TODO figure out why we need to flush stencil settings on path draws at all if (kStencilPath_DrawType != type && fHWStencilSettings != stencilSettings) { if (stencilSettings.isDisabled()) { if (kNo_TriState != fHWStencilTestEnabled) { @@ -1917,10 +1918,7 @@ void GrGpuGL::flushAAState(const GrOptDrawState& optState, DrawType type) { const GrRenderTarget* rt = optState.getRenderTarget(); if (kGL_GrGLStandard == this->glStandard()) { if (RT_HAS_MSAA) { - // FIXME: GL_NV_pr doesn't seem to like MSAA disabled. The paths - // convex hulls of each segment appear to get filled. - bool enableMSAA = kStencilPath_DrawType == type || - optState.isHWAntialiasState(); + bool enableMSAA = optState.isHWAntialiasState(); if (enableMSAA) { if (kYes_TriState != fMSAAEnabled) { GL_CALL(Enable(GR_GL_MULTISAMPLE)); |