blob: f2c02d9e812ee0d69112fbead46a1eb544f6a283 [file] [log] [blame]
kkinnunenccdaa042014-08-20 01:36:23 -07001/*
2 * Copyright 2014 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#ifndef GrPathRendering_DEFINED
9#define GrPathRendering_DEFINED
10
11#include "SkPath.h"
kkinnunencabe20c2015-06-01 01:37:26 -070012#include "GrGpu.h"
cdalton855d83f2014-09-18 13:51:53 -070013#include "GrPathRange.h"
bsalomoncb02b382015-08-12 11:14:50 -070014#include "GrPipeline.h"
kkinnunenccdaa042014-08-20 01:36:23 -070015
cdalton855d83f2014-09-18 13:51:53 -070016class SkDescriptor;
17class SkTypeface;
kkinnunenccdaa042014-08-20 01:36:23 -070018class GrPath;
joshualitt92e496f2014-10-31 13:56:50 -070019class GrStencilSettings;
bsalomon6663acf2016-05-10 09:14:17 -070020class GrStyle;
kkinnunenccdaa042014-08-20 01:36:23 -070021
22/**
23 * Abstract class wrapping HW path rendering API.
24 *
25 * The subclasses of this class use the possible HW API to render paths (as opposed to path
26 * rendering implemented in Skia on top of a "3d" HW API).
27 * The subclasses hold the global state needed to render paths, including shadow of the global HW
28 * API state. Similar to GrGpu.
29 *
30 * It is expected that the lifetimes of GrGpuXX and GrXXPathRendering are the same. The call context
31 * interface (eg. * the concrete instance of GrGpu subclass) should be provided to the instance
32 * during construction.
33 */
34class GrPathRendering {
35public:
36 virtual ~GrPathRendering() { }
37
cdalton55b24af2014-11-25 11:00:56 -080038 typedef GrPathRange::PathIndexType PathIndexType;
joshualitt92e496f2014-10-31 13:56:50 -070039
kkinnunenccdaa042014-08-20 01:36:23 -070040 enum PathTransformType {
41 kNone_PathTransformType, //!< []
42 kTranslateX_PathTransformType, //!< [kMTransX]
43 kTranslateY_PathTransformType, //!< [kMTransY]
44 kTranslate_PathTransformType, //!< [kMTransX, kMTransY]
45 kAffine_PathTransformType, //!< [kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY]
46
47 kLast_PathTransformType = kAffine_PathTransformType
48 };
49
50 static inline int PathTransformSize(PathTransformType type) {
51 switch (type) {
52 case kNone_PathTransformType:
53 return 0;
54 case kTranslateX_PathTransformType:
55 case kTranslateY_PathTransformType:
56 return 1;
57 case kTranslate_PathTransformType:
58 return 2;
59 case kAffine_PathTransformType:
60 return 6;
61
62 default:
63 SkFAIL("Unknown path transform type");
64 return 0;
65 }
66 }
67
cdalton55b24af2014-11-25 11:00:56 -080068 // No native support for inverse at this time
69 enum FillType {
70 /** Specifies that "inside" is computed by a non-zero sum of signed
71 edge crossings
72 */
73 kWinding_FillType,
74 /** Specifies that "inside" is computed by an odd number of edge
75 crossings
76 */
77 kEvenOdd_FillType,
78 };
79
cdalton193d9cf2016-05-12 11:52:02 -070080 static const GrUserStencilSettings& GetStencilPassSettings(FillType);
81
cdalton4e205b12014-09-17 09:41:24 -070082 /**
83 * Creates a new gpu path, based on the specified path and stroke and returns it.
84 * The caller owns a ref on the returned path which must be balanced by a call to unref.
85 *
bsalomon6663acf2016-05-10 09:14:17 -070086 * @param SkPath the geometry.
87 * @param GrStyle the style applied to the path. Styles with non-dash path effects are not
88 * allowed.
89 * @return a new GPU path object.
cdalton4e205b12014-09-17 09:41:24 -070090 */
bsalomon6663acf2016-05-10 09:14:17 -070091 virtual GrPath* createPath(const SkPath&, const GrStyle&) = 0;
cdalton4e205b12014-09-17 09:41:24 -070092
93 /**
bsalomon6663acf2016-05-10 09:14:17 -070094 * Creates a range of gpu paths with a common style. The caller owns a ref on the
cdalton4e205b12014-09-17 09:41:24 -070095 * returned path range which must be balanced by a call to unref.
96 *
97 * @param PathGenerator class that generates SkPath objects for each path in the range.
bsalomon6663acf2016-05-10 09:14:17 -070098 * @param GrStyle the common style applied to each path in the range. Styles with non-dash
99 * path effects are not allowed.
cdalton4e205b12014-09-17 09:41:24 -0700100 * @return a new path range.
101 */
bsalomon6663acf2016-05-10 09:14:17 -0700102 virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*, const GrStyle&) = 0;
cdalton855d83f2014-09-18 13:51:53 -0700103
104 /**
105 * Creates a range of glyph paths, indexed by glyph id. The glyphs will have an
106 * inverted y-direction in order to match the raw font path data. The caller owns
107 * a ref on the returned path range which must be balanced by a call to unref.
108 *
109 * @param SkTypeface Typeface that defines the glyphs.
110 * If null, the default typeface will be used.
111 *
112 * @param SkDescriptor Additional font configuration that specifies the font's size,
113 * stroke, and other flags. This will generally come from an
114 * SkGlyphCache.
115 *
116 * It is recommended to leave this value null when possible, in
117 * which case the glyphs will be loaded directly from the font's
118 * raw path data and sized at SkPaint::kCanonicalTextSizeForPaths.
119 * This will result in less memory usage and more efficient paths.
120 *
121 * If non-null, the glyph paths will match the font descriptor,
122 * including with the stroke information baked directly into
123 * the outlines.
124 *
bsalomon6663acf2016-05-10 09:14:17 -0700125 * @param GrStyle Common style that the GPU will apply to every path. Note that
126 * if the glyph outlines contain baked-in styles from the font
127 * descriptor, the GPU style will be applied on top of those
cdalton855d83f2014-09-18 13:51:53 -0700128 * outlines.
129 *
130 * @return a new path range populated with glyphs.
131 */
reeda9322c22016-04-12 06:47:05 -0700132 GrPathRange* createGlyphs(const SkTypeface*, const SkScalerContextEffects&,
bsalomon6663acf2016-05-10 09:14:17 -0700133 const SkDescriptor*, const GrStyle&);
cdalton4e205b12014-09-17 09:41:24 -0700134
kkinnunencabe20c2015-06-01 01:37:26 -0700135 /** None of these params are optional, pointers used just to avoid making copies. */
136 struct StencilPathArgs {
137 StencilPathArgs(bool useHWAA,
138 GrRenderTarget* renderTarget,
139 const SkMatrix* viewMatrix,
140 const GrScissorState* scissor,
141 const GrStencilSettings* stencil)
142 : fUseHWAA(useHWAA)
143 , fRenderTarget(renderTarget)
144 , fViewMatrix(viewMatrix)
145 , fScissor(scissor)
146 , fStencil(stencil) {
147 }
148 bool fUseHWAA;
149 GrRenderTarget* fRenderTarget;
150 const SkMatrix* fViewMatrix;
151 const GrScissorState* fScissor;
152 const GrStencilSettings* fStencil;
153 };
kkinnunenccdaa042014-08-20 01:36:23 -0700154
kkinnunencabe20c2015-06-01 01:37:26 -0700155 void stencilPath(const StencilPathArgs& args, const GrPath* path) {
156 fGpu->handleDirtyContext();
157 this->onStencilPath(args, path);
158 }
159
stephana1dc17212016-04-25 07:01:22 -0700160 void drawPath(const GrPipeline& pipeline,
161 const GrPrimitiveProcessor& primProc,
cdalton193d9cf2016-05-12 11:52:02 -0700162 const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
stephana1dc17212016-04-25 07:01:22 -0700163 const GrPath* path) {
164 fGpu->handleDirtyContext();
165 if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
166 fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
167 }
cdalton193d9cf2016-05-12 11:52:02 -0700168 this->onDrawPath(pipeline, primProc, stencilPassSettings, path);
stephana1dc17212016-04-25 07:01:22 -0700169 }
170
egdaniel0e1853c2016-03-17 11:35:45 -0700171 void drawPaths(const GrPipeline& pipeline,
172 const GrPrimitiveProcessor& primProc,
cdalton193d9cf2016-05-12 11:52:02 -0700173 const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
egdaniel0e1853c2016-03-17 11:35:45 -0700174 const GrPathRange* pathRange,
175 const void* indices,
176 PathIndexType indexType,
177 const float transformValues[],
178 PathTransformType transformType,
179 int count) {
kkinnunencabe20c2015-06-01 01:37:26 -0700180 fGpu->handleDirtyContext();
egdaniel0e1853c2016-03-17 11:35:45 -0700181 if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
182 fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
bsalomoncb02b382015-08-12 11:14:50 -0700183 }
cdaltond1201052015-10-05 15:56:34 -0700184#ifdef SK_DEBUG
185 pathRange->assertPathsLoaded(indices, indexType, count);
186#endif
cdalton193d9cf2016-05-12 11:52:02 -0700187 this->onDrawPaths(pipeline, primProc, stencilPassSettings, pathRange, indices, indexType,
egdaniel0e1853c2016-03-17 11:35:45 -0700188 transformValues, transformType, count);
kkinnunencabe20c2015-06-01 01:37:26 -0700189 }
bsalomoncb02b382015-08-12 11:14:50 -0700190
kkinnunencabe20c2015-06-01 01:37:26 -0700191protected:
192 GrPathRendering(GrGpu* gpu)
193 : fGpu(gpu) {
194 }
195 virtual void onStencilPath(const StencilPathArgs&, const GrPath*) = 0;
stephana1dc17212016-04-25 07:01:22 -0700196 virtual void onDrawPath(const GrPipeline&,
197 const GrPrimitiveProcessor&,
198 const GrStencilSettings&,
199 const GrPath*) = 0;
egdaniel0e1853c2016-03-17 11:35:45 -0700200 virtual void onDrawPaths(const GrPipeline&,
201 const GrPrimitiveProcessor&,
202 const GrStencilSettings&,
203 const GrPathRange*,
204 const void* indices,
205 PathIndexType,
206 const float transformValues[],
207 PathTransformType,
208 int count) = 0;
kkinnunencabe20c2015-06-01 01:37:26 -0700209
210 GrGpu* fGpu;
kkinnunenccdaa042014-08-20 01:36:23 -0700211private:
212 GrPathRendering& operator=(const GrPathRendering&);
213};
214
215#endif