OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrDefaultPathRenderer.h" | 8 #include "GrDefaultPathRenderer.h" |
9 | 9 |
10 #include "GrContext.h" | 10 #include "GrContext.h" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 #if STENCIL_OFF | 156 #if STENCIL_OFF |
157 return true; | 157 return true; |
158 #else | 158 #else |
159 if (!stroke.isHairlineStyle() && !path.isInverseFillType()) { | 159 if (!stroke.isHairlineStyle() && !path.isInverseFillType()) { |
160 return path.isConvex(); | 160 return path.isConvex(); |
161 } | 161 } |
162 return false; | 162 return false; |
163 #endif | 163 #endif |
164 } | 164 } |
165 | 165 |
166 GrPathRenderer::StencilSupport GrDefaultPathRenderer::onGetStencilSupport( | 166 GrPathRenderer::StencilSupport |
167 const SkPath& path, | 167 GrDefaultPathRenderer::onGetStencilSupport(const GrDrawTarget*, |
168 const SkStrokeRec& s
troke, | 168 const GrDrawState*, |
169 const GrDrawTarget*)
const { | 169 const SkPath& path, |
| 170 const SkStrokeRec& stroke) const { |
170 if (single_pass_path(path, stroke)) { | 171 if (single_pass_path(path, stroke)) { |
171 return GrPathRenderer::kNoRestriction_StencilSupport; | 172 return GrPathRenderer::kNoRestriction_StencilSupport; |
172 } else { | 173 } else { |
173 return GrPathRenderer::kStencilOnly_StencilSupport; | 174 return GrPathRenderer::kStencilOnly_StencilSupport; |
174 } | 175 } |
175 } | 176 } |
176 | 177 |
177 static inline void append_countour_edge_indices(bool hairLine, | 178 static inline void append_countour_edge_indices(bool hairLine, |
178 uint16_t fanCenterIdx, | 179 uint16_t fanCenterIdx, |
179 uint16_t edgeV0Idx, | 180 uint16_t edgeV0Idx, |
180 uint16_t** indices) { | 181 uint16_t** indices) { |
181 // when drawing lines we're appending line segments along | 182 // when drawing lines we're appending line segments along |
182 // the contour. When applying the other fill rules we're | 183 // the contour. When applying the other fill rules we're |
183 // drawing triangle fans around fanCenterIdx. | 184 // drawing triangle fans around fanCenterIdx. |
184 if (!hairLine) { | 185 if (!hairLine) { |
185 *((*indices)++) = fanCenterIdx; | 186 *((*indices)++) = fanCenterIdx; |
186 } | 187 } |
187 *((*indices)++) = edgeV0Idx; | 188 *((*indices)++) = edgeV0Idx; |
188 *((*indices)++) = edgeV0Idx + 1; | 189 *((*indices)++) = edgeV0Idx + 1; |
189 } | 190 } |
190 | 191 |
191 bool GrDefaultPathRenderer::createGeom(const SkPath& path, | 192 bool GrDefaultPathRenderer::createGeom(GrDrawTarget* target, |
192 const SkStrokeRec& stroke, | 193 GrDrawState* drawState, |
193 SkScalar srcSpaceTol, | |
194 GrDrawTarget* target, | |
195 GrPrimitiveType* primType, | 194 GrPrimitiveType* primType, |
196 int* vertexCnt, | 195 int* vertexCnt, |
197 int* indexCnt, | 196 int* indexCnt, |
198 GrDrawTarget::AutoReleaseGeometry* arg) { | 197 GrDrawTarget::AutoReleaseGeometry* arg, |
| 198 const SkPath& path, |
| 199 const SkStrokeRec& stroke, |
| 200 SkScalar srcSpaceTol) { |
199 { | 201 { |
200 SkScalar srcSpaceTolSqd = SkScalarMul(srcSpaceTol, srcSpaceTol); | 202 SkScalar srcSpaceTolSqd = SkScalarMul(srcSpaceTol, srcSpaceTol); |
201 int contourCnt; | 203 int contourCnt; |
202 int maxPts = GrPathUtils::worstCasePointCount(path, &contourCnt, | 204 int maxPts = GrPathUtils::worstCasePointCount(path, &contourCnt, |
203 srcSpaceTol); | 205 srcSpaceTol); |
204 | 206 |
205 if (maxPts <= 0) { | 207 if (maxPts <= 0) { |
206 return false; | 208 return false; |
207 } | 209 } |
208 if (maxPts > ((int)SK_MaxU16 + 1)) { | 210 if (maxPts > ((int)SK_MaxU16 + 1)) { |
(...skipping 15 matching lines...) Expand all Loading... |
224 } | 226 } |
225 } else { | 227 } else { |
226 if (indexed) { | 228 if (indexed) { |
227 maxIdxs = 3 * maxPts; | 229 maxIdxs = 3 * maxPts; |
228 *primType = kTriangles_GrPrimitiveType; | 230 *primType = kTriangles_GrPrimitiveType; |
229 } else { | 231 } else { |
230 *primType = kTriangleFan_GrPrimitiveType; | 232 *primType = kTriangleFan_GrPrimitiveType; |
231 } | 233 } |
232 } | 234 } |
233 | 235 |
234 target->drawState()->setDefaultVertexAttribs(); | 236 drawState->setDefaultVertexAttribs(); |
235 if (!arg->set(target, maxPts, maxIdxs)) { | 237 if (!arg->set(target, maxPts, drawState->getVertexStride(), maxIdxs)) { |
236 return false; | 238 return false; |
237 } | 239 } |
238 | 240 |
239 uint16_t* idxBase = reinterpret_cast<uint16_t*>(arg->indices()); | 241 uint16_t* idxBase = reinterpret_cast<uint16_t*>(arg->indices()); |
240 uint16_t* idx = idxBase; | 242 uint16_t* idx = idxBase; |
241 uint16_t subpathIdxStart = 0; | 243 uint16_t subpathIdxStart = 0; |
242 | 244 |
243 SkPoint* base = reinterpret_cast<SkPoint*>(arg->vertices()); | 245 SkPoint* base = reinterpret_cast<SkPoint*>(arg->vertices()); |
244 SkASSERT(base); | 246 SkASSERT(base); |
245 SkPoint* vert = base; | 247 SkPoint* vert = base; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 SkASSERT((vert - base) <= maxPts); | 319 SkASSERT((vert - base) <= maxPts); |
318 SkASSERT((idx - idxBase) <= maxIdxs); | 320 SkASSERT((idx - idxBase) <= maxIdxs); |
319 | 321 |
320 *vertexCnt = static_cast<int>(vert - base); | 322 *vertexCnt = static_cast<int>(vert - base); |
321 *indexCnt = static_cast<int>(idx - idxBase); | 323 *indexCnt = static_cast<int>(idx - idxBase); |
322 | 324 |
323 } | 325 } |
324 return true; | 326 return true; |
325 } | 327 } |
326 | 328 |
327 bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, | 329 bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target, |
| 330 GrDrawState* drawState, |
| 331 const SkPath& path, |
328 const SkStrokeRec& origStroke, | 332 const SkStrokeRec& origStroke, |
329 GrDrawTarget* target, | |
330 bool stencilOnly) { | 333 bool stencilOnly) { |
331 | 334 SkMatrix viewM = drawState->getViewMatrix(); |
332 SkMatrix viewM = target->getDrawState().getViewMatrix(); | |
333 SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke); | 335 SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke); |
334 | 336 |
335 SkScalar hairlineCoverage; | 337 SkScalar hairlineCoverage; |
336 if (IsStrokeHairlineOrEquivalent(*stroke, target->getDrawState().getViewMatr
ix(), | 338 if (IsStrokeHairlineOrEquivalent(*stroke, drawState->getViewMatrix(), |
337 &hairlineCoverage)) { | 339 &hairlineCoverage)) { |
338 uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage * | 340 uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage * drawState->g
etCoverage()); |
339 target->getDrawState().getCover
age()); | 341 drawState->setCoverage(newCoverage); |
340 target->drawState()->setCoverage(newCoverage); | |
341 | 342 |
342 if (!stroke->isHairlineStyle()) { | 343 if (!stroke->isHairlineStyle()) { |
343 stroke.writable()->setHairlineStyle(); | 344 stroke.writable()->setHairlineStyle(); |
344 } | 345 } |
345 } | 346 } |
346 | 347 |
347 SkScalar tol = SK_Scalar1; | 348 SkScalar tol = SK_Scalar1; |
348 tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds()); | 349 tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds()); |
349 | 350 |
350 int vertexCnt; | 351 int vertexCnt; |
351 int indexCnt; | 352 int indexCnt; |
352 GrPrimitiveType primType; | 353 GrPrimitiveType primType; |
353 GrDrawTarget::AutoReleaseGeometry arg; | 354 GrDrawTarget::AutoReleaseGeometry arg; |
354 if (!this->createGeom(path, | 355 if (!this->createGeom(target, |
355 *stroke, | 356 drawState, |
356 tol, | |
357 target, | |
358 &primType, | 357 &primType, |
359 &vertexCnt, | 358 &vertexCnt, |
360 &indexCnt, | 359 &indexCnt, |
361 &arg)) { | 360 &arg, |
| 361 path, |
| 362 *stroke, |
| 363 tol)) { |
362 return false; | 364 return false; |
363 } | 365 } |
364 | 366 |
365 SkASSERT(target); | |
366 GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit); | |
367 GrDrawState* drawState = target->drawState(); | |
368 bool colorWritesWereDisabled = drawState->isColorWriteDisabled(); | 367 bool colorWritesWereDisabled = drawState->isColorWriteDisabled(); |
369 // face culling doesn't make sense here | 368 // face culling doesn't make sense here |
370 SkASSERT(GrDrawState::kBoth_DrawFace == drawState->getDrawFace()); | 369 SkASSERT(GrDrawState::kBoth_DrawFace == drawState->getDrawFace()); |
371 | 370 |
372 int passCount = 0; | 371 int passCount = 0; |
373 const GrStencilSettings* passes[3]; | 372 const GrStencilSettings* passes[3]; |
374 GrDrawState::DrawFace drawFace[3]; | 373 GrDrawState::DrawFace drawFace[3]; |
375 bool reverse = false; | 374 bool reverse = false; |
376 bool lastPassIsBounds; | 375 bool lastPassIsBounds; |
377 | 376 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 // mapRect through persp matrix may not be correct | 483 // mapRect through persp matrix may not be correct |
485 if (!drawState->getViewMatrix().hasPerspective() && | 484 if (!drawState->getViewMatrix().hasPerspective() && |
486 drawState->getViewInverse(&vmi)) { | 485 drawState->getViewInverse(&vmi)) { |
487 vmi.mapRect(&bounds); | 486 vmi.mapRect(&bounds); |
488 } else { | 487 } else { |
489 avmr.setIdentity(drawState); | 488 avmr.setIdentity(drawState); |
490 } | 489 } |
491 } else { | 490 } else { |
492 bounds = path.getBounds(); | 491 bounds = path.getBounds(); |
493 } | 492 } |
494 GrDrawTarget::AutoGeometryAndStatePush agasp(target, GrDrawTarget::k
Preserve_ASRInit); | 493 GrDrawTarget::AutoGeometryPush agp(target); |
495 target->drawSimpleRect(bounds); | 494 target->drawSimpleRect(drawState, bounds); |
496 } else { | 495 } else { |
497 if (passCount > 1) { | 496 if (passCount > 1) { |
498 drawState->enableState(GrDrawState::kNoColorWrites_StateBit); | 497 drawState->enableState(GrDrawState::kNoColorWrites_StateBit); |
499 } | 498 } |
500 GrDrawState::AutoRestoreEffects are(drawState); | 499 GrDrawState::AutoRestoreEffects are(drawState); |
501 drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(fals
e))->unref(); | 500 drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(fals
e))->unref(); |
502 if (indexCnt) { | 501 if (indexCnt) { |
503 target->drawIndexed(primType, 0, 0, | 502 target->drawIndexed(drawState, |
504 vertexCnt, indexCnt, &devBounds); | 503 primType, |
| 504 0, |
| 505 0, |
| 506 vertexCnt, |
| 507 indexCnt, |
| 508 &devBounds); |
505 } else { | 509 } else { |
506 target->drawNonIndexed(primType, 0, vertexCnt, &devBounds); | 510 target->drawNonIndexed(drawState, primType, 0, vertexCnt, &devBo
unds); |
507 } | 511 } |
508 } | 512 } |
509 } | 513 } |
510 return true; | 514 return true; |
511 } | 515 } |
512 | 516 |
513 bool GrDefaultPathRenderer::canDrawPath(const SkPath& path, | 517 bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target, |
| 518 const GrDrawState* drawState, |
| 519 const SkPath& path, |
514 const SkStrokeRec& stroke, | 520 const SkStrokeRec& stroke, |
515 const GrDrawTarget* target, | |
516 bool antiAlias) const { | 521 bool antiAlias) const { |
517 // this class can draw any path with any fill but doesn't do any anti-aliasi
ng. | 522 // this class can draw any path with any fill but doesn't do any anti-aliasi
ng. |
518 | 523 |
519 return !antiAlias && !(SkPath::kConic_SegmentMask & path.getSegmentMasks())
&& | 524 return !antiAlias && !(SkPath::kConic_SegmentMask & path.getSegmentMasks())
&& |
520 (stroke.isFillStyle() || | 525 (stroke.isFillStyle() || |
521 IsStrokeHairlineOrEquivalent(stroke, target->getDrawState().getViewMatr
ix(), NULL)); | 526 IsStrokeHairlineOrEquivalent(stroke, drawState->getViewMatrix(), NULL))
; |
522 } | 527 } |
523 | 528 |
524 bool GrDefaultPathRenderer::onDrawPath(const SkPath& path, | 529 bool GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, |
| 530 GrDrawState* drawState, |
| 531 const SkPath& path, |
525 const SkStrokeRec& stroke, | 532 const SkStrokeRec& stroke, |
526 GrDrawTarget* target, | |
527 bool antiAlias) { | 533 bool antiAlias) { |
528 return this->internalDrawPath(path, | 534 return this->internalDrawPath(target, |
| 535 drawState, |
| 536 path, |
529 stroke, | 537 stroke, |
530 target, | |
531 false); | 538 false); |
532 } | 539 } |
533 | 540 |
534 void GrDefaultPathRenderer::onStencilPath(const SkPath& path, | 541 void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target, |
535 const SkStrokeRec& stroke, | 542 GrDrawState* drawState, |
536 GrDrawTarget* target) { | 543 const SkPath& path, |
| 544 const SkStrokeRec& stroke) { |
537 SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType()); | 545 SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType()); |
538 SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType()); | 546 SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType()); |
539 this->internalDrawPath(path, stroke, target, true); | 547 this->internalDrawPath(target, drawState, path, stroke, true); |
540 } | 548 } |
OLD | NEW |