Line data Source code
1 : /*
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"
12 : #include "GrGpu.h"
13 : #include "GrPathRange.h"
14 : #include "GrPipeline.h"
15 :
16 : class SkDescriptor;
17 : class SkTypeface;
18 : class GrPath;
19 : class GrStencilSettings;
20 : class GrStyle;
21 :
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 : */
34 : class GrPathRendering {
35 : public:
36 0 : virtual ~GrPathRendering() { }
37 :
38 : typedef GrPathRange::PathIndexType PathIndexType;
39 :
40 : 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 0 : static inline int PathTransformSize(PathTransformType type) {
51 0 : switch (type) {
52 : case kNone_PathTransformType:
53 0 : return 0;
54 : case kTranslateX_PathTransformType:
55 : case kTranslateY_PathTransformType:
56 0 : return 1;
57 : case kTranslate_PathTransformType:
58 0 : return 2;
59 : case kAffine_PathTransformType:
60 0 : return 6;
61 :
62 : default:
63 0 : SkFAIL("Unknown path transform type");
64 0 : return 0;
65 : }
66 : }
67 :
68 : // 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 :
80 : static const GrUserStencilSettings& GetStencilPassSettings(FillType);
81 :
82 : /**
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 : *
86 : * @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.
90 : */
91 : virtual GrPath* createPath(const SkPath&, const GrStyle&) = 0;
92 :
93 : /**
94 : * Creates a range of gpu paths with a common style. The caller owns a ref on the
95 : * 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.
98 : * @param GrStyle the common style applied to each path in the range. Styles with non-dash
99 : * path effects are not allowed.
100 : * @return a new path range.
101 : */
102 : virtual GrPathRange* createPathRange(GrPathRange::PathGenerator*, const GrStyle&) = 0;
103 :
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 : *
125 : * @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
128 : * outlines.
129 : *
130 : * @return a new path range populated with glyphs.
131 : */
132 : GrPathRange* createGlyphs(const SkTypeface*, const SkScalerContextEffects&,
133 : const SkDescriptor*, const GrStyle&);
134 :
135 : /** None of these params are optional, pointers used just to avoid making copies. */
136 : struct StencilPathArgs {
137 0 : StencilPathArgs(bool useHWAA,
138 : GrRenderTarget* renderTarget,
139 : const SkMatrix* viewMatrix,
140 : const GrScissorState* scissor,
141 : const GrStencilSettings* stencil)
142 0 : : fUseHWAA(useHWAA)
143 : , fRenderTarget(renderTarget)
144 : , fViewMatrix(viewMatrix)
145 : , fScissor(scissor)
146 0 : , fStencil(stencil) {
147 0 : }
148 : bool fUseHWAA;
149 : GrRenderTarget* fRenderTarget;
150 : const SkMatrix* fViewMatrix;
151 : const GrScissorState* fScissor;
152 : const GrStencilSettings* fStencil;
153 : };
154 :
155 0 : void stencilPath(const StencilPathArgs& args, const GrPath* path) {
156 0 : fGpu->handleDirtyContext();
157 0 : this->onStencilPath(args, path);
158 0 : }
159 :
160 0 : void drawPath(const GrPipeline& pipeline,
161 : const GrPrimitiveProcessor& primProc,
162 : const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
163 : const GrPath* path) {
164 0 : fGpu->handleDirtyContext();
165 0 : if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
166 0 : fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
167 : }
168 0 : this->onDrawPath(pipeline, primProc, stencilPassSettings, path);
169 0 : }
170 :
171 0 : void drawPaths(const GrPipeline& pipeline,
172 : const GrPrimitiveProcessor& primProc,
173 : const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
174 : const GrPathRange* pathRange,
175 : const void* indices,
176 : PathIndexType indexType,
177 : const float transformValues[],
178 : PathTransformType transformType,
179 : int count) {
180 0 : fGpu->handleDirtyContext();
181 0 : if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
182 0 : fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
183 : }
184 : #ifdef SK_DEBUG
185 0 : pathRange->assertPathsLoaded(indices, indexType, count);
186 : #endif
187 : this->onDrawPaths(pipeline, primProc, stencilPassSettings, pathRange, indices, indexType,
188 0 : transformValues, transformType, count);
189 0 : }
190 :
191 : protected:
192 0 : GrPathRendering(GrGpu* gpu)
193 0 : : fGpu(gpu) {
194 0 : }
195 : virtual void onStencilPath(const StencilPathArgs&, const GrPath*) = 0;
196 : virtual void onDrawPath(const GrPipeline&,
197 : const GrPrimitiveProcessor&,
198 : const GrStencilSettings&,
199 : const GrPath*) = 0;
200 : 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;
209 :
210 : GrGpu* fGpu;
211 : private:
212 : GrPathRendering& operator=(const GrPathRendering&);
213 : };
214 :
215 : #endif
|