Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: src/gpu/gl/GrGLPathRendering.cpp

Issue 450283002: Simplify GrGLPathRendering interface (Closed) Base URL: https://skia.googlesource.com/skia.git@02-path-state-to-pathrendering-class
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "gl/GrGLPathRendering.h" 8 #include "gl/GrGLPathRendering.h"
9 #include "gl/GrGLInterface.h" 9 #include "gl/GrGLInterface.h"
10 #include "gl/GrGLNameAllocator.h" 10 #include "gl/GrGLNameAllocator.h"
(...skipping 28 matching lines...) Expand all
39 default: 39 default:
40 SkFAIL("Unexpected path fill."); 40 SkFAIL("Unexpected path fill.");
41 /* fallthrough */; 41 /* fallthrough */;
42 case kIncClamp_StencilOp: 42 case kIncClamp_StencilOp:
43 return GR_GL_COUNT_UP; 43 return GR_GL_COUNT_UP;
44 case kInvert_StencilOp: 44 case kInvert_StencilOp:
45 return GR_GL_INVERT; 45 return GR_GL_INVERT;
46 } 46 }
47 } 47 }
48 48
49 class GrGLPathRenderingV12 : public GrGLPathRendering {
50 public:
51 GrGLPathRenderingV12(GrGpuGL* gpu, const GrGLInterface* glInterface)
52 : GrGLPathRendering(gpu, glInterface) {
53 }
54
55 virtual GrGLvoid stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
56 GrGLuint mask, GrGLenum coverMode) SK_OVERRIDE;
57 virtual GrGLvoid stencilThenCoverStrokePath(GrGLuint path, GrGLint reference ,
58 GrGLuint mask, GrGLenum coverMod e) SK_OVERRIDE;
59 virtual GrGLvoid stencilThenCoverFillPathInstanced(
60 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvo id *paths,
61 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, Gr GLenum coverMode,
62 GrGLenum transformType, const GrGLfloat *transformValue s) SK_OVERRIDE;
63 virtual GrGLvoid stencilThenCoverStrokePathInstanced(
64 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvo id *paths,
65 GrGLuint pathBase, GrGLint reference, GrGLuint mask, Gr GLenum coverMode,
66 GrGLenum transformType, const GrGLfloat *transformValue s) SK_OVERRIDE;
67 };
68
69 class GrGLPathRenderingV13 : public GrGLPathRenderingV12 {
70 public:
71 GrGLPathRenderingV13(GrGpuGL* gpu, const GrGLInterface* glInterface)
72 : GrGLPathRenderingV12(gpu, glInterface) {
73 fCaps.fragmentInputGenSupport = true;
74 }
75
76 virtual GrGLvoid programPathFragmentInputGen(GrGLuint program, GrGLint locat ion,
77 GrGLenum genMode, GrGLint compo nents,
78 const GrGLfloat *coeffs) SK_OVE RRIDE;
79 };
80
81
82 GrGLPathRendering* GrGLPathRendering::Create(GrGpuGL* gpu, const GrGLInterface* glInterface) {
83 if (NULL == glInterface->fFunctions.fStencilThenCoverFillPath ||
84 NULL == glInterface->fFunctions.fStencilThenCoverStrokePath ||
85 NULL == glInterface->fFunctions.fStencilThenCoverFillPathInstanced ||
86 NULL == glInterface->fFunctions.fStencilThenCoverStrokePathInstanced) {
87 return new GrGLPathRendering(gpu, glInterface);
88 }
89
90 if (NULL == glInterface->fFunctions.fProgramPathFragmentInputGen) {
91 return new GrGLPathRenderingV12(gpu, glInterface);
92 }
93
94 return new GrGLPathRenderingV13(gpu, glInterface);
95 }
96
97 GrGLPathRendering::GrGLPathRendering(GrGpuGL* gpu, const GrGLInterface* glInterf ace) 49 GrGLPathRendering::GrGLPathRendering(GrGpuGL* gpu, const GrGLInterface* glInterf ace)
98 : fGpu(gpu), 50 : fGpu(gpu),
99 fGLInterface(SkRef(glInterface)) { 51 fGLInterface(SkRef(glInterface)) {
100 memset(&fCaps, 0, sizeof(fCaps)); 52 fCaps.thenFunctionsSupport =
53 NULL != glInterface->fFunctions.fStencilThenCoverFillPath &&
54 NULL != glInterface->fFunctions.fStencilThenCoverStrokePath &&
55 NULL != glInterface->fFunctions.fStencilThenCoverFillPathInstanced &&
56 NULL != glInterface->fFunctions.fStencilThenCoverStrokePathInstanced;
57 fCaps.fragmentInputGenSupport =
58 NULL != glInterface->fFunctions.fProgramPathFragmentInputGen;
101 fHWPathTexGenSettings.reset(fGpu->glCaps().maxFixedFunctionTextureCoords()); 59 fHWPathTexGenSettings.reset(fGpu->glCaps().maxFixedFunctionTextureCoords());
102 } 60 }
103 61
104 GrGLPathRendering::~GrGLPathRendering() { 62 GrGLPathRendering::~GrGLPathRendering() {
105 } 63 }
106 64
107 void GrGLPathRendering::abandonGpuResources() { 65 void GrGLPathRendering::abandonGpuResources() {
108 fPathNameAllocator.reset(NULL); 66 fPathNameAllocator.reset(NULL);
109 } 67 }
110 68
111 void GrGLPathRendering::onResetContext() { 69 void GrGLPathRendering::onResetContext() {
112 fHWProjectionMatrixState.invalidate(); 70 fHWProjectionMatrixState.invalidate();
113 // we don't use the model view matrix. 71 // we don't use the model view matrix.
114 GL_CALL(MatrixLoadIdentity(GR_GL_MODELVIEW)); 72 GL_CALL(MatrixLoadIdentity(GR_GL_MODELVIEW));
115 73
116 for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) { 74 for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) {
117 this->pathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL); 75 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
118 fHWPathTexGenSettings[i].fMode = GR_GL_NONE; 76 fHWPathTexGenSettings[i].fMode = GR_GL_NONE;
119 fHWPathTexGenSettings[i].fNumComponents = 0; 77 fHWPathTexGenSettings[i].fNumComponents = 0;
120 } 78 }
121 fHWActivePathTexGenSets = 0; 79 fHWActivePathTexGenSets = 0;
122 fHWPathStencilSettings.invalidate(); 80 fHWPathStencilSettings.invalidate();
123 } 81 }
124 82
125 GrPath* GrGLPathRendering::createPath(const SkPath& inPath, const SkStrokeRec& s troke) { 83 GrPath* GrGLPathRendering::createPath(const SkPath& inPath, const SkStrokeRec& s troke) {
126 return SkNEW_ARGS(GrGLPath, (fGpu, inPath, stroke)); 84 return SkNEW_ARGS(GrGLPath, (fGpu, inPath, stroke));
127 } 85 }
128 86
129 GrPathRange* GrGLPathRendering::createPathRange(size_t size, const SkStrokeRec& stroke) { 87 GrPathRange* GrGLPathRendering::createPathRange(size_t size, const SkStrokeRec& stroke) {
130 return SkNEW_ARGS(GrGLPathRange, (fGpu, size, stroke)); 88 return SkNEW_ARGS(GrGLPathRange, (fGpu, size, stroke));
131 } 89 }
132 90
133 void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents compo nents,
134 const GrGLfloat* coefficients) {
135 SkASSERT(components >= kS_PathTexGenComponents &&
136 components <= kSTR_PathTexGenComponents);
137 SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= unitIdx);
138
139 if (GR_GL_OBJECT_LINEAR == fHWPathTexGenSettings[unitIdx].fMode &&
140 components == fHWPathTexGenSettings[unitIdx].fNumComponents &&
141 !memcmp(coefficients, fHWPathTexGenSettings[unitIdx].fCoefficients,
142 3 * components * sizeof(GrGLfloat))) {
143 return;
144 }
145
146 fGpu->setTextureUnit(unitIdx);
147
148 fHWPathTexGenSettings[unitIdx].fNumComponents = components;
149 this->pathTexGen(GR_GL_TEXTURE0 + unitIdx, GR_GL_OBJECT_LINEAR, components, coefficients);
150
151 memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients,
152 3 * components * sizeof(GrGLfloat));
153 }
154
155 void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents compo nents,
156 const SkMatrix& matrix) {
157 GrGLfloat coefficients[3 * 3];
158 SkASSERT(components >= kS_PathTexGenComponents &&
159 components <= kSTR_PathTexGenComponents);
160
161 coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
162 coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
163 coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
164
165 if (components >= kST_PathTexGenComponents) {
166 coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
167 coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
168 coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
169 }
170
171 if (components >= kSTR_PathTexGenComponents) {
172 coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
173 coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
174 coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
175 }
176
177 this->enablePathTexGen(unitIdx, components, coefficients);
178 }
179
180 void GrGLPathRendering::flushPathTexGenSettings(int numUsedTexCoordSets) {
181 SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= numUsedTexCoordSe ts);
182
183 // Only write the inactive path tex gens, since active path tex gens were
184 // written when they were enabled.
185
186 SkDEBUGCODE(
187 for (int i = 0; i < numUsedTexCoordSets; i++) {
188 SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents);
189 }
190 );
191
192 for (int i = numUsedTexCoordSets; i < fHWActivePathTexGenSets; i++) {
193 SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents);
194
195 fGpu->setTextureUnit(i);
196 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
197 fHWPathTexGenSettings[i].fNumComponents = 0;
198 }
199
200 fHWActivePathTexGenSets = numUsedTexCoordSets;
201 }
202
203 void GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) { 91 void GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) {
204 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); 92 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
205 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()); 93 SkASSERT(NULL != fGpu->drawState()->getRenderTarget());
206 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer()); 94 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer());
207 95
208 this->flushPathStencilSettings(fill); 96 this->flushPathStencilSettings(fill);
209 97
210 GrGLenum fillMode = 98 GrGLenum fillMode =
211 gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.pass Op(GrStencilSettings::kFront_Face)); 99 gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.pass Op(GrStencilSettings::kFront_Face));
212 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro nt_Face); 100 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro nt_Face);
213 this->stencilFillPath(id, fillMode, writeMask); 101 GL_CALL(StencilFillPath(id, fillMode, writeMask));
214 } 102 }
215 103
216 void GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) { 104 void GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) {
217 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); 105 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
218 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()); 106 SkASSERT(NULL != fGpu->drawState()->getRenderTarget());
219 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer()); 107 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer());
220 SkASSERT(!fGpu->fCurrentProgram->hasVertexShader()); 108 SkASSERT(!fGpu->fCurrentProgram->hasVertexShader());
221 109
222 this->flushPathStencilSettings(fill); 110 this->flushPathStencilSettings(fill);
223 const SkStrokeRec& stroke = path->getStroke(); 111 const SkStrokeRec& stroke = path->getStroke();
224 112
225 SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill) ; 113 SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill) ;
226 SkASSERT(!fHWPathStencilSettings.isTwoSided()); 114 SkASSERT(!fHWPathStencilSettings.isTwoSided());
227 GrGLenum fillMode = 115 GrGLenum fillMode =
228 gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.pass Op(GrStencilSettings::kFront_Face)); 116 gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.pass Op(GrStencilSettings::kFront_Face));
229 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro nt_Face); 117 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro nt_Face);
230 118
231 if (nonInvertedFill == fill) { 119 if (nonInvertedFill == fill) {
232 if (stroke.needToApply()) { 120 if (stroke.needToApply()) {
233 if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { 121 if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
234 this->stencilFillPath(id, fillMode, writeMask); 122 GL_CALL(StencilFillPath(id, fillMode, writeMask));
235 } 123 }
236 this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDI NG_BOX); 124 this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDI NG_BOX);
237 } else { 125 } else {
238 this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDI NG_BOX); 126 this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDI NG_BOX);
239 } 127 }
240 } else { 128 } else {
241 if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke. getStyle()) { 129 if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke. getStyle()) {
242 this->stencilFillPath(id, fillMode, writeMask); 130 GL_CALL(StencilFillPath(id, fillMode, writeMask));
243 } 131 }
244 if (stroke.needToApply()) { 132 if (stroke.needToApply()) {
245 this->stencilStrokePath(id, 0xffff, writeMask); 133 GL_CALL(StencilStrokePath(id, 0xffff, writeMask));
246 } 134 }
247 135
248 GrDrawState* drawState = fGpu->drawState(); 136 GrDrawState* drawState = fGpu->drawState();
249 GrDrawState::AutoViewMatrixRestore avmr; 137 GrDrawState::AutoViewMatrixRestore avmr;
250 SkRect bounds = SkRect::MakeLTRB(0, 0, 138 SkRect bounds = SkRect::MakeLTRB(0, 0,
251 SkIntToScalar(drawState->getRenderTarge t()->width()), 139 SkIntToScalar(drawState->getRenderTarge t()->width()),
252 SkIntToScalar(drawState->getRenderTarge t()->height())); 140 SkIntToScalar(drawState->getRenderTarge t()->height()));
253 SkMatrix vmi; 141 SkMatrix vmi;
254 // mapRect through persp matrix may not be correct 142 // mapRect through persp matrix may not be correct
255 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn verse(&vmi)) { 143 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn verse(&vmi)) {
(...skipping 29 matching lines...) Expand all
285 SkASSERT(!fHWPathStencilSettings.isTwoSided()); 173 SkASSERT(!fHWPathStencilSettings.isTwoSided());
286 GrGLenum fillMode = 174 GrGLenum fillMode =
287 gr_stencil_op_to_gl_path_rendering_fill_mode( 175 gr_stencil_op_to_gl_path_rendering_fill_mode(
288 fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); 176 fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
289 GrGLint writeMask = 177 GrGLint writeMask =
290 fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); 178 fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
291 179
292 if (nonInvertedFill == fill) { 180 if (nonInvertedFill == fill) {
293 if (stroke.needToApply()) { 181 if (stroke.needToApply()) {
294 if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { 182 if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
295 this->stencilFillPathInstanced( 183 GL_CALL(StencilFillPathInstanced(
296 count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, 184 count, GR_GL_UNSIGNED_INT, indices, baseID, fill Mode,
297 writeMask, gXformType2GLType[transformsType] , 185 writeMask, gXformType2GLType[transformsType],
298 transforms); 186 transforms));
299 } 187 }
300 this->stencilThenCoverStrokePathInstanced( 188 this->stencilThenCoverStrokePathInstanced(
301 count, GR_GL_UNSIGNED_INT, indices, baseID, 0xff ff, writeMask, 189 count, GR_GL_UNSIGNED_INT, indices, baseID, 0xff ff, writeMask,
302 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, 190 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
303 gXformType2GLType[transformsType], transforms); 191 gXformType2GLType[transformsType], transforms);
304 } else { 192 } else {
305 this->stencilThenCoverFillPathInstanced( 193 this->stencilThenCoverFillPathInstanced(
306 count, GR_GL_UNSIGNED_INT, indices, baseID, fill Mode, writeMask, 194 count, GR_GL_UNSIGNED_INT, indices, baseID, fill Mode, writeMask,
307 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, 195 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
308 gXformType2GLType[transformsType], transforms); 196 gXformType2GLType[transformsType], transforms);
309 } 197 }
310 } else { 198 } else {
311 if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke. getStyle()) { 199 if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke. getStyle()) {
312 this->stencilFillPathInstanced( 200 GL_CALL(StencilFillPathInstanced(
313 count, GR_GL_UNSIGNED_INT, indices, baseID, fill Mode, 201 count, GR_GL_UNSIGNED_INT, indices, baseID, fill Mode,
314 writeMask, gXformType2GLType[transformsType], 202 writeMask, gXformType2GLType[transformsType],
315 transforms); 203 transforms));
316 } 204 }
317 if (stroke.needToApply()) { 205 if (stroke.needToApply()) {
318 this->stencilStrokePathInstanced( 206 GL_CALL(StencilStrokePathInstanced(
319 count, GR_GL_UNSIGNED_INT, indices, baseID, 0xff ff, 207 count, GR_GL_UNSIGNED_INT, indices, baseID, 0xff ff,
320 writeMask, gXformType2GLType[transformsType], 208 writeMask, gXformType2GLType[transformsType],
321 transforms); 209 transforms));
322 } 210 }
323 211
324 GrDrawState* drawState = fGpu->drawState(); 212 GrDrawState* drawState = fGpu->drawState();
325 GrDrawState::AutoViewMatrixRestore avmr; 213 GrDrawState::AutoViewMatrixRestore avmr;
326 SkRect bounds = SkRect::MakeLTRB(0, 0, 214 SkRect bounds = SkRect::MakeLTRB(0, 0,
327 SkIntToScalar(drawState->getRenderTarge t()->width()), 215 SkIntToScalar(drawState->getRenderTarge t()->width()),
328 SkIntToScalar(drawState->getRenderTarge t()->height())); 216 SkIntToScalar(drawState->getRenderTarge t()->height()));
329 SkMatrix vmi; 217 SkMatrix vmi;
330 // mapRect through persp matrix may not be correct 218 // mapRect through persp matrix may not be correct
331 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn verse(&vmi)) { 219 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn verse(&vmi)) {
332 vmi.mapRect(&bounds); 220 vmi.mapRect(&bounds);
333 // theoretically could set bloat = 0, instead leave it because of ma trix inversion 221 // theoretically could set bloat = 0, instead leave it because of ma trix inversion
334 // precision. 222 // precision.
335 SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_Scala rHalf; 223 SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_Scala rHalf;
336 bounds.outset(bloat, bloat); 224 bounds.outset(bloat, bloat);
337 } else { 225 } else {
338 avmr.setIdentity(drawState); 226 avmr.setIdentity(drawState);
339 } 227 }
340 228
341 fGpu->drawSimpleRect(bounds); 229 fGpu->drawSimpleRect(bounds);
342 } 230 }
343 } 231 }
344 232
345 void GrGLPathRendering::flushPathStencilSettings(SkPath::FillType fill) { 233 void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents compo nents,
346 GrStencilSettings pathStencilSettings; 234 const GrGLfloat* coefficients) {
347 fGpu->getPathStencilSettingsForFillType(fill, &pathStencilSettings); 235 SkASSERT(components >= kS_PathTexGenComponents &&
348 if (fHWPathStencilSettings != pathStencilSettings) { 236 components <= kSTR_PathTexGenComponents);
349 // Just the func, ref, and mask is set here. The op and write mask are p arams to the call 237 SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= unitIdx);
350 // that draws the path to the SB (glStencilFillPath)
351 GrGLenum func =
352 GrToGLStencilFunc(pathStencilSettings.func(GrStencilSettings::kFront _Face));
353 this->pathStencilFunc(func, pathStencilSettings.funcRef(GrStencilSetting s::kFront_Face),
354 pathStencilSettings.funcMask(GrStencilSettings::kF ront_Face));
355 238
356 fHWPathStencilSettings = pathStencilSettings; 239 if (GR_GL_OBJECT_LINEAR == fHWPathTexGenSettings[unitIdx].fMode &&
240 components == fHWPathTexGenSettings[unitIdx].fNumComponents &&
241 !memcmp(coefficients, fHWPathTexGenSettings[unitIdx].fCoefficients,
242 3 * components * sizeof(GrGLfloat))) {
243 return;
357 } 244 }
245
246 fGpu->setTextureUnit(unitIdx);
247
248 fHWPathTexGenSettings[unitIdx].fNumComponents = components;
249 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + unitIdx, GR_GL_OBJECT_LINEAR, components , coefficients));
250
251 memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients,
252 3 * components * sizeof(GrGLfloat));
253 }
254
255 void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents compo nents,
256 const SkMatrix& matrix) {
257 GrGLfloat coefficients[3 * 3];
258 SkASSERT(components >= kS_PathTexGenComponents &&
259 components <= kSTR_PathTexGenComponents);
260
261 coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
262 coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
263 coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
264
265 if (components >= kST_PathTexGenComponents) {
266 coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
267 coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
268 coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
269 }
270
271 if (components >= kSTR_PathTexGenComponents) {
272 coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
273 coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
274 coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
275 }
276
277 this->enablePathTexGen(unitIdx, components, coefficients);
278 }
279
280 void GrGLPathRendering::flushPathTexGenSettings(int numUsedTexCoordSets) {
281 SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= numUsedTexCoordSe ts);
282
283 // Only write the inactive path tex gens, since active path tex gens were
284 // written when they were enabled.
285
286 SkDEBUGCODE(
287 for (int i = 0; i < numUsedTexCoordSets; i++) {
288 SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents);
289 }
290 );
291
292 for (int i = numUsedTexCoordSets; i < fHWActivePathTexGenSets; i++) {
293 SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents);
294
295 fGpu->setTextureUnit(i);
296 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
297 fHWPathTexGenSettings[i].fNumComponents = 0;
298 }
299
300 fHWActivePathTexGenSets = numUsedTexCoordSets;
301 }
302
303 void GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, G rGLint location,
304 GrGLenum genMode, G rGLint components,
305 const SkMatrix& mat rix) {
306 SkASSERT(caps().fragmentInputGenSupport);
307 GrGLfloat coefficients[3 * 3];
308 SkASSERT(components >= 1 && components <= 3);
309
310 coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
311 coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
312 coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
313
314 if (components >= 2) {
315 coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
316 coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
317 coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
318 }
319
320 if (components >= 3) {
321 coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
322 coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
323 coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
324 }
325
326 GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, coefficients));
358 } 327 }
359 328
360 void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix, 329 void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix,
361 const SkISize& renderTargetSize, 330 const SkISize& renderTargetSize,
362 GrSurfaceOrigin renderTargetOrigin) { 331 GrSurfaceOrigin renderTargetOrigin) {
363 332
364 SkASSERT(fGpu->glCaps().pathRenderingSupport()); 333 SkASSERT(fGpu->glCaps().pathRenderingSupport());
365 334
366 if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin && 335 if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin &&
367 renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize && 336 renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize &&
368 matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) { 337 matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) {
369 return; 338 return;
370 } 339 }
371 340
372 fHWProjectionMatrixState.fViewMatrix = matrix; 341 fHWProjectionMatrixState.fViewMatrix = matrix;
373 fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize; 342 fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize;
374 fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin; 343 fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin;
375 344
376 GrGLfloat glMatrix[4 * 4]; 345 GrGLfloat glMatrix[4 * 4];
377 fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix); 346 fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix);
378 GL_CALL(MatrixLoadf(GR_GL_PROJECTION, glMatrix)); 347 GL_CALL(MatrixLoadf(GR_GL_PROJECTION, glMatrix));
379 } 348 }
380 349
381
382
383 // NV_path_rendering
384 GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) { 350 GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) {
385 if (range > 1) { 351 if (range > 1) {
386 GrGLuint name; 352 GrGLuint name;
387 GL_CALL_RET(name, GenPaths(range)); 353 GL_CALL_RET(name, GenPaths(range));
388 return name; 354 return name;
389 } 355 }
390 356
391 if (NULL == fPathNameAllocator.get()) { 357 if (NULL == fPathNameAllocator.get()) {
392 static const int range = 65536; 358 static const int range = 65536;
393 GrGLuint firstName; 359 GrGLuint firstName;
394 GL_CALL_RET(firstName, GenPaths(range)); 360 GL_CALL_RET(firstName, GenPaths(range));
395 fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, first Name + range))); 361 fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, first Name + range)));
396 } 362 }
397 363
398 // When allocating names one at a time, pull from a client-side pool of 364 // When allocating names one at a time, pull from a client-side pool of
399 // available names in order to save a round trip to the GL server. 365 // available names in order to save a round trip to the GL server.
400 GrGLuint name = fPathNameAllocator->allocateName(); 366 GrGLuint name = fPathNameAllocator->allocateName();
401 367
402 if (0 == name) { 368 if (0 == name) {
403 // Our reserved path names are all in use. Fall back on GenPaths. 369 // Our reserved path names are all in use. Fall back on GenPaths.
404 GL_CALL_RET(name, GenPaths(1)); 370 GL_CALL_RET(name, GenPaths(1));
405 } 371 }
406 372
407 return name; 373 return name;
408 } 374 }
409 375
410 GrGLvoid GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) { 376 void GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) {
411 if (range > 1) { 377 if (range > 1) {
412 // It is not supported to delete names in ranges that were allocated 378 // It is not supported to delete names in ranges that were allocated
413 // individually using GrGLPathNameAllocator. 379 // individually using GrGLPathNameAllocator.
414 SkASSERT(NULL == fPathNameAllocator.get() || 380 SkASSERT(NULL == fPathNameAllocator.get() ||
415 path + range <= fPathNameAllocator->firstName() || 381 path + range <= fPathNameAllocator->firstName() ||
416 path >= fPathNameAllocator->endName()); 382 path >= fPathNameAllocator->endName());
417 GL_CALL(DeletePaths(path, range)); 383 GL_CALL(DeletePaths(path, range));
418 return; 384 return;
419 } 385 }
420 386
421 if (NULL == fPathNameAllocator.get() || 387 if (NULL == fPathNameAllocator.get() ||
422 path < fPathNameAllocator->firstName() || 388 path < fPathNameAllocator->firstName() ||
423 path >= fPathNameAllocator->endName()) { 389 path >= fPathNameAllocator->endName()) {
424 // If we aren't inside fPathNameAllocator's range then this name was 390 // If we aren't inside fPathNameAllocator's range then this name was
425 // generated by the GenPaths fallback (or else was never allocated). 391 // generated by the GenPaths fallback (or else was never allocated).
426 GL_CALL(DeletePaths(path, 1)); 392 GL_CALL(DeletePaths(path, 1));
427 return; 393 return;
428 } 394 }
429 395
430 // Make the path empty to save memory, but don't free the name in the driver . 396 // Make the path empty to save memory, but don't free the name in the driver .
431 GL_CALL(PathCommands(path, 0, NULL, 0, GR_GL_FLOAT, NULL)); 397 GL_CALL(PathCommands(path, 0, NULL, 0, GR_GL_FLOAT, NULL));
432 fPathNameAllocator->free(path); 398 fPathNameAllocator->free(path);
433 } 399 }
434 400
435 GrGLvoid GrGLPathRendering::pathCommands(GrGLuint path, GrGLsizei numCommands, 401 void GrGLPathRendering::flushPathStencilSettings(SkPath::FillType fill) {
436 const GrGLubyte *commands, GrGLsizei nu mCoords, 402 GrStencilSettings pathStencilSettings;
437 GrGLenum coordType, const GrGLvoid *coo rds) { 403 fGpu->getPathStencilSettingsForFillType(fill, &pathStencilSettings);
438 GL_CALL(PathCommands(path, numCommands, commands, numCoords, coordType, coor ds)); 404 if (fHWPathStencilSettings != pathStencilSettings) {
405 // Just the func, ref, and mask is set here. The op and write mask are p arams to the call
406 // that draws the path to the SB (glStencilFillPath)
407 GrGLenum func =
408 GrToGLStencilFunc(pathStencilSettings.func(GrStencilSettings::kFront _Face));
409 GL_CALL(PathStencilFunc(func, pathStencilSettings.funcRef(GrStencilSetti ngs::kFront_Face),
410 pathStencilSettings.funcMask(GrStencilSettings:: kFront_Face)));
411
412 fHWPathStencilSettings = pathStencilSettings;
413 }
439 } 414 }
440 415
441 GrGLvoid GrGLPathRendering::pathCoords(GrGLuint path, GrGLsizei numCoords, 416 inline void GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
442 GrGLenum coordType, const GrGLvoid *coord s) {
443 GL_CALL(PathCoords(path, numCoords, coordType, coords));
444 }
445
446 GrGLvoid GrGLPathRendering::pathParameteri(GrGLuint path, GrGLenum pname, GrGLin t value) {
447 GL_CALL(PathParameteri(path, pname, value));
448 }
449
450 GrGLvoid GrGLPathRendering::pathParameterf(GrGLuint path, GrGLenum pname, GrGLfl oat value) {
451 GL_CALL(PathParameterf(path, pname, value));
452 }
453
454 GrGLboolean GrGLPathRendering::isPath(GrGLuint path) {
455 GrGLboolean ret;
456 GL_CALL_RET(ret, IsPath(path));
457 return ret;
458 }
459
460 GrGLvoid GrGLPathRendering::pathStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) {
461 GL_CALL(PathStencilFunc(func, ref, mask));
462 }
463
464 GrGLvoid GrGLPathRendering::stencilFillPath(GrGLuint path, GrGLenum fillMode, Gr GLuint mask) {
465 // Decide how to manipulate the stencil buffer based on the fill rule.
466 SkASSERT(!fHWPathStencilSettings.isTwoSided());
467
468 GL_CALL(StencilFillPath(path, fillMode, mask));
469 }
470
471 GrGLvoid GrGLPathRendering::stencilStrokePath(GrGLuint path, GrGLint reference, GrGLuint mask) {
472 GL_CALL(StencilStrokePath(path, reference, mask));
473 }
474
475 GrGLvoid GrGLPathRendering::stencilFillPathInstanced(
476 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
477 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask,
478 GrGLenum transformType, const GrGLfloat *transformValues) {
479 GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase,
480 fillMode, mask, transformType, transformVal ues));
481 }
482
483 GrGLvoid GrGLPathRendering::stencilStrokePathInstanced(
484 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
485 GrGLuint pathBase, GrGLint reference, GrGLuint mask,
486 GrGLenum transformType, const GrGLfloat *transformValues) {
487 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
488 reference, mask, transformType, transform Values));
489 }
490
491 GrGLvoid GrGLPathRendering::pathTexGen(GrGLenum texCoordSet, GrGLenum genMode,
492 GrGLint components, const GrGLfloat *coef fs) {
493 GL_CALL(PathTexGen(texCoordSet, genMode, components, coeffs));
494 }
495
496 GrGLvoid GrGLPathRendering::coverFillPath(GrGLuint path, GrGLenum coverMode) {
497 GL_CALL(CoverFillPath(path, coverMode));
498 }
499
500 GrGLvoid GrGLPathRendering::coverStrokePath(GrGLuint name, GrGLenum coverMode) {
501 GL_CALL(CoverStrokePath(name, coverMode));
502 }
503
504 GrGLvoid GrGLPathRendering::coverFillPathInstanced(
505 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, G rGLuint pathBase,
506 GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transf ormValues) {
507 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase,
508 coverMode, transformType, transformValues));
509 }
510
511 GrGLvoid GrGLPathRendering::coverStrokePathInstanced(
512 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, G rGLuint pathBase,
513 GrGLenum coverMode, GrGLenum transformType, const GrGLfloat* transf ormValues) {
514 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
515 coverMode, transformType, transformValues)) ;
516 }
517
518 GrGLvoid GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fil lMode,
519 GrGLuint mask, GrGLenum cov erMode) { 417 GrGLuint mask, GrGLenum cov erMode) {
418 if (caps().thenFunctionsSupport) {
419 GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode));
420 return;
421 }
520 GL_CALL(StencilFillPath(path, fillMode, mask)); 422 GL_CALL(StencilFillPath(path, fillMode, mask));
521 GL_CALL(CoverFillPath(path, coverMode)); 423 GL_CALL(CoverFillPath(path, coverMode));
522 } 424 }
523 425
524 GrGLvoid GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint re ference, 426 inline void GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
525 GrGLuint mask, GrGLenum c overMode) { 427 GrGLuint mask, GrGLenum c overMode) {
428 if (caps().thenFunctionsSupport) {
429 GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode));
430 return;
431 }
526 GL_CALL(StencilStrokePath(path, reference, mask)); 432 GL_CALL(StencilStrokePath(path, reference, mask));
527 GL_CALL(CoverStrokePath(path, coverMode)); 433 GL_CALL(CoverStrokePath(path, coverMode));
528 } 434 }
529 435
530 GrGLvoid GrGLPathRendering::stencilThenCoverFillPathInstanced( 436 inline void GrGLPathRendering::stencilThenCoverFillPathInstanced(
531 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, 437 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
532 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum cover Mode, 438 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum cover Mode,
533 GrGLenum transformType, const GrGLfloat *transformValues) { 439 GrGLenum transformType, const GrGLfloat *transformValues) {
440 if (caps().thenFunctionsSupport) {
441 GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode,
442 mask, coverMode, transformType , transformValues));
443 return;
444 }
534 GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, 445 GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase,
535 fillMode, mask, transformType, transformVal ues)); 446 fillMode, mask, transformType, transformVal ues));
536 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, 447 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase,
537 coverMode, transformType, transformValues)); 448 coverMode, transformType, transformValues));
538 } 449 }
539 450
540 GrGLvoid GrGLPathRendering::stencilThenCoverStrokePathInstanced( 451 inline void GrGLPathRendering::stencilThenCoverStrokePathInstanced(
541 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, 452 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
542 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum cover Mode, 453 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
543 GrGLenum transformType, const GrGLfloat *transformValues) { 454 GrGLenum transformType, const GrGLfloat *transformValues) {
455 if (caps().thenFunctionsSupport) {
456 GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, path s, pathBase,
457 reference, mask, coverMode, transformType,
458 transformValues));
459 return;
460 }
461
544 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, 462 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
545 reference, mask, transformType, transform Values)); 463 reference, mask, transformType, transform Values));
546 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, 464 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
547 coverMode, transformType, transformValues)) ; 465 coverMode, transformType, transformValues)) ;
548 } 466 }
549
550 GrGLvoid GrGLPathRendering::programPathFragmentInputGen(
551 GrGLuint program, GrGLint location, GrGLenum genMode,
552 GrGLint components, const GrGLfloat *coeffs) {
553 SkFAIL("ProgramPathFragmentInputGen not supported in this GL context.");
554 }
555
556
557 // NV_path_rendering v1.2
558 GrGLvoid GrGLPathRenderingV12::stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
559 GrGLuint mask, GrGLenum coverMode) {
560 GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode));
561 }
562
563 GrGLvoid GrGLPathRenderingV12::stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
564 GrGLuint mask, GrGLenu m coverMode) {
565 GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode));
566 }
567
568 GrGLvoid GrGLPathRenderingV12::stencilThenCoverFillPathInstanced(
569 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
570 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum cover Mode,
571 GrGLenum transformType, const GrGLfloat *transformValues) {
572 GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pat hBase, fillMode,
573 mask, coverMode, transformType, t ransformValues));
574 }
575
576 GrGLvoid GrGLPathRenderingV12::stencilThenCoverStrokePathInstanced(
577 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
578 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum cover Mode,
579 GrGLenum transformType, const GrGLfloat *transformValues) {
580 GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, p athBase, reference,
581 mask, coverMode, transformType, transformValues));
582 }
583
584
585 // NV_path_rendering v1.3
586 GrGLvoid GrGLPathRenderingV13::programPathFragmentInputGen(
587 GrGLuint program, GrGLint location, GrGLenum genMode,
588 GrGLint components, const GrGLfloat *coeffs) {
589 GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, coeffs));
590 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698