1/* 2 * Copyright 2011 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 "src/gpu/v1/PathRenderer.h" 9 10#include "include/gpu/GrRecordingContext.h" 11#include "src/core/SkDrawProcs.h" 12#include "src/gpu/GrCaps.h" 13#include "src/gpu/GrPaint.h" 14#include "src/gpu/GrRecordingContextPriv.h" 15#include "src/gpu/GrUserStencilSettings.h" 16#include "src/gpu/geometry/GrStyledShape.h" 17#ifdef SK_DEBUG 18#include "src/gpu/v1/SurfaceDrawContext_v1.h" 19#endif 20 21namespace skgpu::v1 { 22 23#ifdef SK_DEBUG 24void PathRenderer::StencilPathArgs::validate() const { 25 SkASSERT(fContext); 26 SkASSERT(fSurfaceDrawContext); 27 SkASSERT(fClipConservativeBounds); 28 SkASSERT(fViewMatrix); 29 SkASSERT(fShape); 30 SkASSERT(fShape->style().isSimpleFill()); 31 SkPath path; 32 fShape->asPath(&path); 33 SkASSERT(!path.isInverseFillType()); 34} 35#endif 36 37////////////////////////////////////////////////////////////////////////////// 38 39PathRenderer::StencilSupport PathRenderer::getStencilSupport(const GrStyledShape& shape) const { 40 SkDEBUGCODE(SkPath path;) 41 SkDEBUGCODE(shape.asPath(&path);) 42 SkASSERT(shape.style().isSimpleFill()); 43 SkASSERT(!path.isInverseFillType()); 44 return this->onGetStencilSupport(shape); 45} 46 47bool PathRenderer::drawPath(const DrawPathArgs& args) { 48#ifdef SK_DEBUG 49 args.validate(); 50 CanDrawPathArgs canArgs; 51 canArgs.fCaps = args.fContext->priv().caps(); 52 canArgs.fProxy = args.fSurfaceDrawContext->asRenderTargetProxy(); 53 canArgs.fClipConservativeBounds = args.fClipConservativeBounds; 54 canArgs.fViewMatrix = args.fViewMatrix; 55 canArgs.fShape = args.fShape; 56 canArgs.fPaint = &args.fPaint; 57 canArgs.fSurfaceProps = &args.fSurfaceDrawContext->surfaceProps(); 58 canArgs.fAAType = args.fAAType; 59 canArgs.validate(); 60 61 canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused(); 62 SkASSERT(CanDrawPath::kNo != this->canDrawPath(canArgs)); 63 if (!args.fUserStencilSettings->isUnused()) { 64 SkPath path; 65 args.fShape->asPath(&path); 66 SkASSERT(args.fShape->style().isSimpleFill()); 67 SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fShape)); 68 } 69#endif 70 return this->onDrawPath(args); 71} 72 73void PathRenderer::GetPathDevBounds(const SkPath& path, 74 SkISize devSize, 75 const SkMatrix& matrix, 76 SkRect* bounds) { 77 if (path.isInverseFillType()) { 78 *bounds = SkRect::Make(devSize); 79 return; 80 } 81 *bounds = path.getBounds(); 82 matrix.mapRect(bounds); 83} 84 85void PathRenderer::onStencilPath(const StencilPathArgs& args) { 86 static constexpr GrUserStencilSettings kIncrementStencil( 87 GrUserStencilSettings::StaticInit< 88 0xffff, 89 GrUserStencilTest::kAlways, 90 0xffff, 91 GrUserStencilOp::kReplace, 92 GrUserStencilOp::kReplace, 93 0xffff>() 94 ); 95 96 GrPaint paint; 97 DrawPathArgs drawArgs{args.fContext, 98 std::move(paint), 99 &kIncrementStencil, 100 args.fSurfaceDrawContext, 101 nullptr, // clip 102 args.fClipConservativeBounds, 103 args.fViewMatrix, 104 args.fShape, 105 (GrAA::kYes == args.fDoStencilMSAA) ? GrAAType::kMSAA : GrAAType::kNone, 106 false}; 107 this->drawPath(drawArgs); 108} 109 110} // namespace skgpu::v1 111