blob: f13a190829e8b48b4742f17c4b9ea6a8c96bd0ec [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;
kkinnunen50b58e62015-05-18 23:02:07 -070020class GrStrokeInfo;
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
cdalton4e205b12014-09-17 09:41:24 -070080 /**
81 * Creates a new gpu path, based on the specified path and stroke and returns it.
82 * The caller owns a ref on the returned path which must be balanced by a call to unref.
83 *
84 * @param skPath the path geometry.
85 * @param stroke the path stroke.
86 * @return a new path.
87 */
kkinnunen50b58e62015-05-18 23:02:07 -070088 virtual GrPath* createPath(const SkPath&, const GrStrokeInfo&) = 0;
cdalton4e205b12014-09-17 09:41:24 -070089
90 /**
91 * Creates a range of gpu paths with a common stroke. The caller owns a ref on the
92 * returned path range which must be balanced by a call to unref.
93 *
94 * @param PathGenerator class that generates SkPath objects for each path in the range.
kkinnunen50b58e62015-05-18 23:02:07 -070095 * @param GrStrokeInfo the common stroke applied to each path in the range.
cdalton4e205b12014-09-17 09:41:24 -070096 * @return a new path range.
97 */
kkinnunen50b58e62015-05-18 23:02:07 -070098 virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*, const GrStrokeInfo&) = 0;
cdalton855d83f2014-09-18 13:51:53 -070099
100 /**
101 * Creates a range of glyph paths, indexed by glyph id. The glyphs will have an
102 * inverted y-direction in order to match the raw font path data. The caller owns
103 * a ref on the returned path range which must be balanced by a call to unref.
104 *
105 * @param SkTypeface Typeface that defines the glyphs.
106 * If null, the default typeface will be used.
107 *
108 * @param SkDescriptor Additional font configuration that specifies the font's size,
109 * stroke, and other flags. This will generally come from an
110 * SkGlyphCache.
111 *
112 * It is recommended to leave this value null when possible, in
113 * which case the glyphs will be loaded directly from the font's
114 * raw path data and sized at SkPaint::kCanonicalTextSizeForPaths.
115 * This will result in less memory usage and more efficient paths.
116 *
117 * If non-null, the glyph paths will match the font descriptor,
118 * including with the stroke information baked directly into
119 * the outlines.
120 *
kkinnunen50b58e62015-05-18 23:02:07 -0700121 * @param GrStrokeInfo Common stroke that the GPU will apply to every path. Note that
cdalton855d83f2014-09-18 13:51:53 -0700122 * if the glyph outlines contain baked-in strokes from the font
123 * descriptor, the GPU stroke will be applied on top of those
124 * outlines.
125 *
126 * @return a new path range populated with glyphs.
127 */
kkinnunen591a2ca2015-06-23 07:27:40 -0700128 GrPathRange* createGlyphs(const SkTypeface*, const SkDescriptor*, const GrStrokeInfo&);
cdalton4e205b12014-09-17 09:41:24 -0700129
kkinnunencabe20c2015-06-01 01:37:26 -0700130 /** None of these params are optional, pointers used just to avoid making copies. */
131 struct StencilPathArgs {
132 StencilPathArgs(bool useHWAA,
133 GrRenderTarget* renderTarget,
134 const SkMatrix* viewMatrix,
135 const GrScissorState* scissor,
136 const GrStencilSettings* stencil)
137 : fUseHWAA(useHWAA)
138 , fRenderTarget(renderTarget)
139 , fViewMatrix(viewMatrix)
140 , fScissor(scissor)
141 , fStencil(stencil) {
142 }
143 bool fUseHWAA;
144 GrRenderTarget* fRenderTarget;
145 const SkMatrix* fViewMatrix;
146 const GrScissorState* fScissor;
147 const GrStencilSettings* fStencil;
148 };
kkinnunenccdaa042014-08-20 01:36:23 -0700149
kkinnunencabe20c2015-06-01 01:37:26 -0700150 void stencilPath(const StencilPathArgs& args, const GrPath* path) {
151 fGpu->handleDirtyContext();
152 this->onStencilPath(args, path);
153 }
154
155 struct DrawPathArgs : public GrGpu::DrawArgs {
156 DrawPathArgs(const GrPrimitiveProcessor* primProc,
157 const GrPipeline* pipeline,
158 const GrProgramDesc* desc,
159 const GrBatchTracker* batchTracker,
160 const GrStencilSettings* stencil)
161 : DrawArgs(primProc, pipeline, desc, batchTracker)
162 , fStencil(stencil) {
163 }
164
165 const GrStencilSettings* fStencil;
166 };
167
168 void drawPath(const DrawPathArgs& args, const GrPath* path) {
169 fGpu->handleDirtyContext();
bsalomoncb02b382015-08-12 11:14:50 -0700170 if (GrXferBarrierType barrierType = args.fPipeline->xferBarrierType(*fGpu->caps())) {
171 fGpu->xferBarrier(args.fPipeline->getRenderTarget(), barrierType);
172 }
kkinnunencabe20c2015-06-01 01:37:26 -0700173 this->onDrawPath(args, path);
174 }
175
176 void drawPaths(const DrawPathArgs& args, const GrPathRange* pathRange, const void* indices,
177 PathIndexType indexType, const float transformValues[],
178 PathTransformType transformType, int count) {
179 fGpu->handleDirtyContext();
bsalomoncb02b382015-08-12 11:14:50 -0700180 if (GrXferBarrierType barrierType = args.fPipeline->xferBarrierType(*fGpu->caps())) {
181 fGpu->xferBarrier(args.fPipeline->getRenderTarget(), barrierType);
182 }
kkinnunencabe20c2015-06-01 01:37:26 -0700183 pathRange->willDrawPaths(indices, indexType, count);
184 this->onDrawPaths(args, pathRange, indices, indexType, transformValues, transformType,
185 count);
186 }
bsalomoncb02b382015-08-12 11:14:50 -0700187
kkinnunencabe20c2015-06-01 01:37:26 -0700188protected:
189 GrPathRendering(GrGpu* gpu)
190 : fGpu(gpu) {
191 }
192 virtual void onStencilPath(const StencilPathArgs&, const GrPath*) = 0;
193 virtual void onDrawPath(const DrawPathArgs&, const GrPath*) = 0;
194 virtual void onDrawPaths(const DrawPathArgs&, const GrPathRange*, const void*, PathIndexType,
195 const float[], PathTransformType, int) = 0;
196
197 GrGpu* fGpu;
kkinnunenccdaa042014-08-20 01:36:23 -0700198private:
199 GrPathRendering& operator=(const GrPathRendering&);
200};
201
202#endif