Use correct fill type and bounds for NVPR paths that are stroked with Skia
authorkkinnunen <kkinnunen@nvidia.com>
Tue, 8 Dec 2015 07:39:01 +0000 (23:39 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 8 Dec 2015 07:39:01 +0000 (23:39 -0800)
When using NVPR, sometimes paths must be stroked by Skia and then drawn
with fill using NVPR. In these cases, use the fill type and bounds of
the stroked path, not the original path.

Fixes degeneratesegments for nvprmsaa backends.

BUG=skia:4608

Review URL: https://codereview.chromium.org/1504753003

src/gpu/GrPath.h
src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
src/gpu/gl/GrGLPath.cpp

index 2edfd4cb5e60bf960e3ecda7f0cf1e6d5ad8aa37..09d317ef2f2d3d0883c01933c67151091b68da20 100644 (file)
 
 #include "GrGpuResource.h"
 #include "GrStrokeInfo.h"
+#include "GrPathRendering.h"
 #include "SkPath.h"
 #include "SkRect.h"
 
 class GrPath : public GrGpuResource {
 public:
-    
-
     /**
      * Initialize to a path with a fixed stroke. Stroke must not be hairline.
      */
     GrPath(GrGpu* gpu, const SkPath& skPath, const GrStrokeInfo& stroke)
         : INHERITED(gpu, kCached_LifeCycle)
-        , fBounds(skPath.getBounds())
+        , fBounds(SkRect::MakeEmpty())
+        , fFillType(GrPathRendering::kWinding_FillType)
 #ifdef SK_DEBUG
         , fSkPath(skPath)
         , fStroke(stroke)
@@ -35,12 +35,15 @@ public:
 
     const SkRect& getBounds() const { return fBounds; }
 
+    GrPathRendering::FillType getFillType() const { return fFillType; }
 #ifdef SK_DEBUG
     bool isEqualTo(const SkPath& path, const GrStrokeInfo& stroke) const;
 #endif
 
 protected:
+    // Subclass should init these.
     SkRect fBounds;
+    GrPathRendering::FillType fFillType;
 #ifdef SK_DEBUG
     SkPath fSkPath;
     GrStrokeInfo fStroke;
index a11d2b468345120c3b499a5877aa812c016c2edd..cf5db3fc630d294686a22902a23daf3fc1a66bcd 100644 (file)
 #include "GrResourceProvider.h"
 #include "GrStrokeInfo.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(GrResourceProvider* resourceProvider,
                                                       const GrCaps& caps) {
     if (caps.shaderCaps()->pathRenderingSupport()) {
@@ -80,8 +64,7 @@ static GrPath* get_gr_path(GrResourceProvider* resourceProvider, const SkPath& s
 void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
     SkASSERT(!args.fPath->isInverseFillType());
     SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, *args.fPath, *args.fStroke));
-    args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fViewMatrix, p,
-                              convert_skpath_filltype(args.fPath->getFillType()));
+    args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fViewMatrix, p, p->getFillType());
 }
 
 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
@@ -114,8 +97,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
         pipelineBuilder->setStencil(kInvertedStencilPass);
 
         // fake inverse with a stencil and cover
-        args.fTarget->stencilPath(*pipelineBuilder, viewMatrix, p,
-                                  convert_skpath_filltype(path.getFillType()));
+        args.fTarget->stencilPath(*pipelineBuilder, viewMatrix, p, p->getFillType());
 
         SkMatrix invert = SkMatrix::I();
         SkRect bounds =
@@ -149,8 +131,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
             0xffff);
 
         pipelineBuilder->setStencil(kStencilPass);
-        args.fTarget->drawPath(*pipelineBuilder, viewMatrix, args.fColor, p,
-                               convert_skpath_filltype(path.getFillType()));
+        args.fTarget->drawPath(*pipelineBuilder, viewMatrix, args.fColor, p, p->getFillType());
     }
 
     pipelineBuilder->stencil()->setDisabled();
index d1fc39dffcc554e22035ced711275323b2baa9fb..067b74e1549d4ab259b0a70f4307d4fa67fa73ac 100644 (file)
@@ -179,6 +179,23 @@ inline bool init_path_object_for_general_path(GrGLGpu* gpu, GrGLuint pathID,
                                                 pathCoords.count(), GR_GL_FLOAT, &pathCoords[0]));
     return true;
 }
+
+/*
+ * 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;
+    }
+}
+
 } // namespace
 
 bool GrGLPath::InitPathObjectPathDataCheckingDegenerates(GrGLGpu* gpu, GrGLuint pathID,
@@ -292,6 +309,9 @@ GrGLPath::GrGLPath(GrGLGpu* gpu, const SkPath& origSkPath, const GrStrokeInfo& o
         fShouldFill = stroke->isFillStyle() ||
                 stroke->getStyle() == SkStrokeRec::kStrokeAndFill_Style;
 
+        fFillType = convert_skpath_filltype(skPath->getFillType());
+        fBounds = skPath->getBounds();
+
         if (fShouldStroke) {
             InitPathObjectStroke(gpu, fPathID, *stroke);