Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrStencilAndCoverPathRenderer.cpp
index 5f55c1a..6ed4b9e 100644 (file)
 #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;
 }