blob: b773249e078245876157bae9da25a8506c3bd23f [file] [log] [blame]
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +00006 */
7
8#ifndef GrPathRenderer_DEFINED
9#define GrPathRenderer_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkRefCnt.h"
12#include "include/private/GrTypesPriv.h"
13#include "include/private/SkTArray.h"
bsalomon@google.com49313f62011-09-14 13:54:05 +000014
Brian Salomon653f42f2018-07-10 10:07:31 -040015class GrCaps;
16class GrClip;
Chris Daltonbbfd5162017-11-07 13:35:22 -070017class GrHardClip;
Brian Salomon653f42f2018-07-10 10:07:31 -040018class GrPaint;
Robert Phillips6f0e02f2019-02-13 11:02:28 -050019class GrRecordingContext;
Brian Salomoneebe7352020-12-09 16:37:04 -050020class GrSurfaceDrawContext;
Chris Daltoneffee202019-07-01 22:28:03 -060021class GrRenderTargetProxy;
Michael Ludwig2686d692020-04-17 20:21:37 +000022class GrStyledShape;
Brian Salomon653f42f2018-07-10 10:07:31 -040023class GrStyle;
24struct GrUserStencilSettings;
25struct SkIRect;
26class SkMatrix;
27class SkPath;
Chris Dalton8e3bca62021-04-26 15:49:21 -060028class SkSurfaceProps;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000029
30/**
Greg Danielf41b2bd2019-08-22 16:19:24 -040031 * Base class for drawing paths into a GrOpsTask.
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000032 */
Brian Salomon57f211b2019-08-21 15:21:09 -040033class GrPathRenderer : public SkRefCnt {
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000034public:
bsalomon@google.comc2099d22012-03-02 21:26:50 +000035 GrPathRenderer();
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000036
Robert Phillipsa6286052020-04-13 10:55:08 -040037 virtual const char* name() const = 0;
38
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000039 /**
bsalomon@google.com45a15f52012-12-10 19:10:17 +000040 * A caller may wish to use a path renderer to draw a path into the stencil buffer. However,
41 * the path renderer itself may require use of the stencil buffer. Also a path renderer may
joshualittb0a8a372014-09-23 09:50:21 -070042 * use a GrProcessor coverage stage that sets coverage to zero to eliminate pixels that are
43 * covered by bounding geometry but outside the path. These exterior pixels would still be
44 * rendered into the stencil.
bsalomon@google.com45a15f52012-12-10 19:10:17 +000045 *
46 * A GrPathRenderer can provide three levels of support for stenciling paths:
Brian Salomone5b399e2017-07-19 13:50:54 -040047 * 1) kNoRestriction: This is the most general. The caller passes a GrPaint and calls drawPath().
48 * The path is rendered exactly as the draw state indicates including support
49 * for simultaneous color and stenciling with arbitrary stenciling rules.
50 * Pixels partially covered by AA paths are affected by the stencil settings.
bsalomon@google.com45a15f52012-12-10 19:10:17 +000051 * 2) kStencilOnly: The path renderer cannot apply arbitrary stencil rules nor shade and stencil
52 * simultaneously. The path renderer does support the stencilPath() function
53 * which performs no color writes and writes a non-zero stencil value to pixels
54 * covered by the path.
55 * 3) kNoSupport: This path renderer cannot be used to stencil the path.
56 */
robertphillips68737822015-10-29 12:12:21 -070057 enum StencilSupport {
58 kNoSupport_StencilSupport,
59 kStencilOnly_StencilSupport,
60 kNoRestriction_StencilSupport,
61 };
bsalomon@google.com45a15f52012-12-10 19:10:17 +000062
63 /**
robertphillips@google.come79f3202014-02-11 16:30:21 +000064 * This function is to get the stencil support for a particular path. The path's fill must
bsalomond6f25bf2016-05-05 09:26:21 -070065 * not be an inverse type. The path will always be filled and not stroked.
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000066 *
bsalomon8acedde2016-06-24 10:42:16 -070067 * @param shape the shape that will be drawn. Must be simple fill styled and non-inverse
68 * filled.
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000069 */
Michael Ludwig2686d692020-04-17 20:21:37 +000070 StencilSupport getStencilSupport(const GrStyledShape& shape) const;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +000071
Chris Dalton5ed44232017-09-07 13:22:46 -060072 enum class CanDrawPath {
73 kNo,
74 kAsBackup, // i.e. This renderer is better than SW fallback if no others can draw the path.
75 kYes
76 };
77
bsalomon0aff2fa2015-07-31 06:48:27 -070078 struct CanDrawPathArgs {
Chris Daltondb91c6e2017-09-08 16:25:08 -060079 SkDEBUGCODE(CanDrawPathArgs() { memset(this, 0, sizeof(*this)); }) // For validation.
80
Eric Karl5c779752017-05-08 12:02:07 -070081 const GrCaps* fCaps;
Chris Daltoneffee202019-07-01 22:28:03 -060082 const GrRenderTargetProxy* fProxy;
Chris Daltondb91c6e2017-09-08 16:25:08 -060083 const SkIRect* fClipConservativeBounds;
bsalomon0aff2fa2015-07-31 06:48:27 -070084 const SkMatrix* fViewMatrix;
Michael Ludwig2686d692020-04-17 20:21:37 +000085 const GrStyledShape* fShape;
Ethan Nicholasafe2c902020-04-28 13:55:02 -040086 const GrPaint* fPaint;
Chris Dalton8e3bca62021-04-26 15:49:21 -060087 const SkSurfaceProps* fSurfaceProps;
Chris Dalton6ce447a2019-06-23 18:07:38 -060088 GrAAType fAAType;
robertphillipse7d4b2f2015-08-13 07:57:10 -070089
Robert Phillips31798c22021-03-18 13:32:56 -040090 // This is only used by GrTessellationPathRenderer
cdalton93a379b2016-05-11 13:58:08 -070091 bool fHasUserStencilSettings;
robertphillips68737822015-10-29 12:12:21 -070092
bsalomon8acedde2016-06-24 10:42:16 -070093#ifdef SK_DEBUG
robertphillipse7d4b2f2015-08-13 07:57:10 -070094 void validate() const {
Eric Karl5c779752017-05-08 12:02:07 -070095 SkASSERT(fCaps);
Chris Daltoneffee202019-07-01 22:28:03 -060096 SkASSERT(fProxy);
Chris Daltondb91c6e2017-09-08 16:25:08 -060097 SkASSERT(fClipConservativeBounds);
robertphillipse7d4b2f2015-08-13 07:57:10 -070098 SkASSERT(fViewMatrix);
bsalomon8acedde2016-06-24 10:42:16 -070099 SkASSERT(fShape);
Chris Dalton8e3bca62021-04-26 15:49:21 -0600100 SkASSERT(fSurfaceProps);
robertphillipse7d4b2f2015-08-13 07:57:10 -0700101 }
bsalomon8acedde2016-06-24 10:42:16 -0700102#endif
bsalomon0aff2fa2015-07-31 06:48:27 -0700103 };
104
bsalomon@google.com208236d2012-03-12 13:15:33 +0000105 /**
Chris Dalton5ed44232017-09-07 13:22:46 -0600106 * Returns how well this path renderer is able to render the given path. Returning kNo or
107 * kAsBackup allows the caller to keep searching for a better path renderer. This function is
108 * called when searching for the best path renderer to draw a path.
bsalomon@google.com208236d2012-03-12 13:15:33 +0000109 */
Chris Dalton5ed44232017-09-07 13:22:46 -0600110 CanDrawPath canDrawPath(const CanDrawPathArgs& args) const {
robertphillipse7d4b2f2015-08-13 07:57:10 -0700111 SkDEBUGCODE(args.validate();)
bsalomon0aff2fa2015-07-31 06:48:27 -0700112 return this->onCanDrawPath(args);
113 }
114
bsalomon0aff2fa2015-07-31 06:48:27 -0700115 struct DrawPathArgs {
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500116 GrRecordingContext* fContext;
Brian Salomon82f44312017-01-11 13:42:54 -0500117 GrPaint&& fPaint;
118 const GrUserStencilSettings* fUserStencilSettings;
John Stiles0fbc6a32021-06-04 14:40:57 -0400119 GrSurfaceDrawContext* fSurfaceDrawContext;
Brian Salomon82f44312017-01-11 13:42:54 -0500120 const GrClip* fClip;
Chris Daltondb91c6e2017-09-08 16:25:08 -0600121 const SkIRect* fClipConservativeBounds;
Brian Salomon82f44312017-01-11 13:42:54 -0500122 const SkMatrix* fViewMatrix;
Michael Ludwig2686d692020-04-17 20:21:37 +0000123 const GrStyledShape* fShape;
Chris Dalton6ce447a2019-06-23 18:07:38 -0600124 GrAAType fAAType;
Brian Salomon82f44312017-01-11 13:42:54 -0500125 bool fGammaCorrect;
bsalomon8acedde2016-06-24 10:42:16 -0700126#ifdef SK_DEBUG
robertphillipse7d4b2f2015-08-13 07:57:10 -0700127 void validate() const {
Robert Phillips256c37b2017-03-01 14:32:46 -0500128 SkASSERT(fContext);
robertphillips976f5f02016-06-03 10:59:20 -0700129 SkASSERT(fUserStencilSettings);
John Stiles0fbc6a32021-06-04 14:40:57 -0400130 SkASSERT(fSurfaceDrawContext);
Chris Daltondb91c6e2017-09-08 16:25:08 -0600131 SkASSERT(fClipConservativeBounds);
robertphillipse7d4b2f2015-08-13 07:57:10 -0700132 SkASSERT(fViewMatrix);
bsalomon8acedde2016-06-24 10:42:16 -0700133 SkASSERT(fShape);
robertphillipse7d4b2f2015-08-13 07:57:10 -0700134 }
bsalomon8acedde2016-06-24 10:42:16 -0700135#endif
bsalomon0aff2fa2015-07-31 06:48:27 -0700136 };
137
bsalomon@google.comee435122011-07-01 14:57:55 +0000138 /**
robertphillips@google.come79f3202014-02-11 16:30:21 +0000139 * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then
Brian Salomone5b399e2017-07-19 13:50:54 -0400140 * the subclass must respect the stencil settings.
bsalomon@google.comee435122011-07-01 14:57:55 +0000141 */
Brian Salomon653f42f2018-07-10 10:07:31 -0400142 bool drawPath(const DrawPathArgs& args);
Chris Daltondb91c6e2017-09-08 16:25:08 -0600143 /**
144 * Args to stencilPath(). fAAType cannot be kCoverage.
bsalomon0aff2fa2015-07-31 06:48:27 -0700145 */
146 struct StencilPathArgs {
Chris Daltondb91c6e2017-09-08 16:25:08 -0600147 SkDEBUGCODE(StencilPathArgs() { memset(this, 0, sizeof(*this)); }) // For validation.
148
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500149 GrRecordingContext* fContext;
John Stiles0fbc6a32021-06-04 14:40:57 -0400150 GrSurfaceDrawContext* fSurfaceDrawContext;
Chris Daltonbbfd5162017-11-07 13:35:22 -0700151 const GrHardClip* fClip;
Chris Daltondb91c6e2017-09-08 16:25:08 -0600152 const SkIRect* fClipConservativeBounds;
Brian Osman11052242016-10-27 14:47:55 -0400153 const SkMatrix* fViewMatrix;
Michael Ludwig2686d692020-04-17 20:21:37 +0000154 const GrStyledShape* fShape;
Chris Dalton09e56892019-03-13 00:22:01 -0600155 GrAA fDoStencilMSAA;
robertphillipse7d4b2f2015-08-13 07:57:10 -0700156
Brian Salomon653f42f2018-07-10 10:07:31 -0400157 SkDEBUGCODE(void validate() const);
bsalomon0aff2fa2015-07-31 06:48:27 -0700158 };
159
bsalomon@google.comee435122011-07-01 14:57:55 +0000160 /**
robertphillips@google.come79f3202014-02-11 16:30:21 +0000161 * Draws the path to the stencil buffer. Assume the writable stencil bits are already
162 * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards.
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000163 */
bsalomon0aff2fa2015-07-31 06:48:27 -0700164 void stencilPath(const StencilPathArgs& args) {
robertphillipse7d4b2f2015-08-13 07:57:10 -0700165 SkDEBUGCODE(args.validate();)
bsalomon8acedde2016-06-24 10:42:16 -0700166 SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fShape));
bsalomon0aff2fa2015-07-31 06:48:27 -0700167 this->onStencilPath(args);
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000168 }
169
170protected:
bsalomon@google.com1dd9baa2013-05-20 16:49:06 +0000171 // Helper for getting the device bounds of a path. Inverse filled paths will have bounds set
172 // by devSize. Non-inverse path bounds will not necessarily be clipped to devSize.
173 static void GetPathDevBounds(const SkPath& path,
Brian Salomon9f2b86c2019-10-22 10:37:46 -0400174 SkISize devSize,
bsalomon@google.com1dd9baa2013-05-20 16:49:06 +0000175 const SkMatrix& matrix,
176 SkRect* bounds);
177
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000178private:
bsalomon0aff2fa2015-07-31 06:48:27 -0700179 /**
180 * Subclass overrides if it has any limitations of stenciling support.
181 */
Michael Ludwig2686d692020-04-17 20:21:37 +0000182 virtual StencilSupport onGetStencilSupport(const GrStyledShape&) const {
bsalomon0aff2fa2015-07-31 06:48:27 -0700183 return kNoRestriction_StencilSupport;
184 }
185
186 /**
187 * Subclass implementation of drawPath()
188 */
189 virtual bool onDrawPath(const DrawPathArgs& args) = 0;
190
191 /**
192 * Subclass implementation of canDrawPath()
193 */
Chris Dalton5ed44232017-09-07 13:22:46 -0600194 virtual CanDrawPath onCanDrawPath(const CanDrawPathArgs& args) const = 0;
bsalomon0aff2fa2015-07-31 06:48:27 -0700195
196 /**
197 * Subclass implementation of stencilPath(). Subclass must override iff it ever returns
198 * kStencilOnly in onGetStencilSupport().
199 */
Brian Salomon653f42f2018-07-10 10:07:31 -0400200 virtual void onStencilPath(const StencilPathArgs&);
bsalomon0aff2fa2015-07-31 06:48:27 -0700201
John Stiles7571f9e2020-09-02 22:42:33 -0400202 using INHERITED = SkRefCnt;
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000203};
204
bsalomon@google.comdfe75bc2011-03-25 12:31:16 +0000205#endif