| 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 |