LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu/ops - GrStencilAndCoverPathRenderer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 65 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2012 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #include "GrStencilAndCoverPathRenderer.h"
       9             : #include "GrCaps.h"
      10             : #include "GrContext.h"
      11             : #include "GrDrawPathOp.h"
      12             : #include "GrFixedClip.h"
      13             : #include "GrGpu.h"
      14             : #include "GrPath.h"
      15             : #include "GrPipelineBuilder.h"
      16             : #include "GrRenderTarget.h"
      17             : #include "GrRenderTargetContextPriv.h"
      18             : #include "GrResourceProvider.h"
      19             : #include "GrStencilPathOp.h"
      20             : #include "GrStyle.h"
      21             : #include "ops/GrRectOpFactory.h"
      22             : 
      23           0 : GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrResourceProvider* resourceProvider,
      24             :                                                       const GrCaps& caps) {
      25           0 :     if (caps.shaderCaps()->pathRenderingSupport()) {
      26           0 :         return new GrStencilAndCoverPathRenderer(resourceProvider);
      27             :     } else {
      28           0 :         return nullptr;
      29             :     }
      30             : }
      31             : 
      32           0 : GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrResourceProvider* resourceProvider)
      33           0 :     : fResourceProvider(resourceProvider) {
      34           0 : }
      35             : 
      36           0 : bool GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
      37             :     // GrPath doesn't support hairline paths. An arbitrary path effect could produce a hairline
      38             :     // path.
      39           0 :     if (args.fShape->style().strokeRec().isHairlineStyle() ||
      40           0 :         args.fShape->style().hasNonDashPathEffect()) {
      41           0 :         return false;
      42             :     }
      43           0 :     if (args.fHasUserStencilSettings) {
      44           0 :         return false;
      45             :     }
      46             :     // doesn't do per-path AA, relies on the target having MSAA.
      47           0 :     return (GrAAType::kCoverage != args.fAAType);
      48             : }
      49             : 
      50           0 : static GrPath* get_gr_path(GrResourceProvider* resourceProvider, const GrShape& shape) {
      51           0 :     GrUniqueKey key;
      52             :     bool isVolatile;
      53           0 :     GrPath::ComputeKey(shape, &key, &isVolatile);
      54           0 :     sk_sp<GrPath> path;
      55           0 :     if (!isVolatile) {
      56             :         path.reset(
      57           0 :             static_cast<GrPath*>(resourceProvider->findAndRefResourceByUniqueKey(key)));
      58             :     }
      59           0 :     if (!path) {
      60           0 :         SkPath skPath;
      61           0 :         shape.asPath(&skPath);
      62           0 :         path.reset(resourceProvider->createPath(skPath, shape.style()));
      63           0 :         if (!isVolatile) {
      64           0 :             resourceProvider->assignUniqueKeyToResource(key, path.get());
      65             :         }
      66             :     } else {
      67             : #ifdef SK_DEBUG
      68           0 :         SkPath skPath;
      69           0 :         shape.asPath(&skPath);
      70           0 :         SkASSERT(path->isEqualTo(skPath, shape.style()));
      71             : #endif
      72             :     }
      73           0 :     return path.release();
      74             : }
      75             : 
      76           0 : void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
      77           0 :     GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
      78             :                               "GrStencilAndCoverPathRenderer::onStencilPath");
      79           0 :     sk_sp<GrPath> p(get_gr_path(fResourceProvider, *args.fShape));
      80           0 :     args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fAAType,
      81           0 :                                                   *args.fViewMatrix, p.get());
      82           0 : }
      83             : 
      84           0 : bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
      85           0 :     GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
      86             :                               "GrStencilAndCoverPathRenderer::onDrawPath");
      87           0 :     SkASSERT(!args.fShape->style().strokeRec().isHairlineStyle());
      88             : 
      89           0 :     const SkMatrix& viewMatrix = *args.fViewMatrix;
      90             : 
      91             : 
      92           0 :     sk_sp<GrPath> path(get_gr_path(fResourceProvider, *args.fShape));
      93             : 
      94           0 :     if (args.fShape->inverseFilled()) {
      95           0 :         SkMatrix invert = SkMatrix::I();
      96             :         SkRect bounds =
      97             :             SkRect::MakeLTRB(0, 0,
      98           0 :                              SkIntToScalar(args.fRenderTargetContext->width()),
      99           0 :                              SkIntToScalar(args.fRenderTargetContext->height()));
     100             :         SkMatrix vmi;
     101             :         // mapRect through persp matrix may not be correct
     102           0 :         if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) {
     103           0 :             vmi.mapRect(&bounds);
     104             :             // theoretically could set bloat = 0, instead leave it because of matrix inversion
     105             :             // precision.
     106           0 :             SkScalar bloat = viewMatrix.getMaxScale() * SK_ScalarHalf;
     107           0 :             bounds.outset(bloat, bloat);
     108             :         } else {
     109           0 :             if (!viewMatrix.invert(&invert)) {
     110           0 :                 return false;
     111             :             }
     112             :         }
     113           0 :         const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : viewMatrix;
     114             : 
     115             :         std::unique_ptr<GrLegacyMeshDrawOp> coverOp(GrRectOpFactory::MakeNonAAFill(
     116           0 :                 args.fPaint.getColor(), viewM, bounds, nullptr, &invert));
     117             : 
     118             :         // fake inverse with a stencil and cover
     119           0 :         args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fAAType, viewMatrix,
     120           0 :                                                       path.get());
     121             : 
     122             :         {
     123             :             static constexpr GrUserStencilSettings kInvertedCoverPass(
     124             :                 GrUserStencilSettings::StaticInit<
     125             :                     0x0000,
     126             :                     // We know our rect will hit pixels outside the clip and the user bits will
     127             :                     // be 0 outside the clip. So we can't just fill where the user bits are 0. We
     128             :                     // also need to check that the clip bit is set.
     129             :                     GrUserStencilTest::kEqualIfInClip,
     130             :                     0xffff,
     131             :                     GrUserStencilOp::kKeep,
     132             :                     GrUserStencilOp::kZero,
     133             :                     0xffff>()
     134             :             );
     135             :             // We have to suppress enabling MSAA for mixed samples or we will get seams due to
     136             :             // coverage modulation along the edge where two triangles making up the rect meet.
     137           0 :             GrAAType coverAAType = args.fAAType;
     138           0 :             if (GrAAType::kMixedSamples == coverAAType) {
     139           0 :                 coverAAType = GrAAType::kNone;
     140             :             }
     141           0 :             GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), coverAAType);
     142           0 :             pipelineBuilder.setUserStencil(&kInvertedCoverPass);
     143             : 
     144           0 :             args.fRenderTargetContext->addLegacyMeshDrawOp(std::move(pipelineBuilder), *args.fClip,
     145           0 :                                                            std::move(coverOp));
     146             :         }
     147             :     } else {
     148             :         std::unique_ptr<GrDrawOp> op =
     149           0 :                 GrDrawPathOp::Make(viewMatrix, std::move(args.fPaint), args.fAAType, path.get());
     150           0 :         args.fRenderTargetContext->addDrawOp(*args.fClip, std::move(op));
     151             :     }
     152             : 
     153           0 :     return true;
     154             : }

Generated by: LCOV version 1.13