| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "GrOvalRenderer.h" | 8 #include "GrOvalRenderer.h" |
| 9 | 9 |
| 10 #include "GrProcessor.h" | 10 #include "GrProcessor.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 | 52 |
| 53 /////////////////////////////////////////////////////////////////////////////// | 53 /////////////////////////////////////////////////////////////////////////////// |
| 54 | 54 |
| 55 /** | 55 /** |
| 56 * The output of this effect is a modulation of the input color and coverage for
a circle, | 56 * The output of this effect is a modulation of the input color and coverage for
a circle, |
| 57 * specified as offset_x, offset_y (both from center point), outer radius and in
ner radius. | 57 * specified as offset_x, offset_y (both from center point), outer radius and in
ner radius. |
| 58 */ | 58 */ |
| 59 | 59 |
| 60 class CircleEdgeEffect : public GrGeometryProcessor { | 60 class CircleEdgeEffect : public GrGeometryProcessor { |
| 61 public: | 61 public: |
| 62 static GrGeometryProcessor* Create(bool stroke) { | 62 static GrGeometryProcessor* Create(GrColor color, bool stroke) { |
| 63 return SkNEW_ARGS(CircleEdgeEffect, (stroke)); | 63 return SkNEW_ARGS(CircleEdgeEffect, (color, stroke)); |
| 64 } | 64 } |
| 65 | 65 |
| 66 const GrAttribute* inPosition() const { return fInPosition; } | 66 const GrAttribute* inPosition() const { return fInPosition; } |
| 67 const GrAttribute* inCircleEdge() const { return fInCircleEdge; } | 67 const GrAttribute* inCircleEdge() const { return fInCircleEdge; } |
| 68 virtual ~CircleEdgeEffect() {} | 68 virtual ~CircleEdgeEffect() {} |
| 69 | 69 |
| 70 virtual const char* name() const SK_OVERRIDE { return "CircleEdge"; } | 70 virtual const char* name() const SK_OVERRIDE { return "CircleEdge"; } |
| 71 | 71 |
| 72 inline bool isStroked() const { return fStroke; } | 72 inline bool isStroked() const { return fStroke; } |
| 73 | 73 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 const GrGLCaps& caps, | 124 const GrGLCaps& caps, |
| 125 GrProcessorKeyBuilder* b) const SK_OVERRIDE { | 125 GrProcessorKeyBuilder* b) const SK_OVERRIDE { |
| 126 GLProcessor::GenKey(*this, bt, caps, b); | 126 GLProcessor::GenKey(*this, bt, caps, b); |
| 127 } | 127 } |
| 128 | 128 |
| 129 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) co
nst SK_OVERRIDE { | 129 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) co
nst SK_OVERRIDE { |
| 130 return SkNEW_ARGS(GLProcessor, (*this, bt)); | 130 return SkNEW_ARGS(GLProcessor, (*this, bt)); |
| 131 } | 131 } |
| 132 | 132 |
| 133 private: | 133 private: |
| 134 CircleEdgeEffect(bool stroke) { | 134 CircleEdgeEffect(GrColor color, bool stroke) : INHERITED(color) { |
| 135 this->initClassID<CircleEdgeEffect>(); | 135 this->initClassID<CircleEdgeEffect>(); |
| 136 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); | 136 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); |
| 137 fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge", | 137 fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge", |
| 138 kVec4f_GrVertexAttrib
Type)); | 138 kVec4f_GrVertexAttrib
Type)); |
| 139 fStroke = stroke; | 139 fStroke = stroke; |
| 140 } | 140 } |
| 141 | 141 |
| 142 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { | 142 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { |
| 143 const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>(); | 143 const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>(); |
| 144 return cee.fStroke == fStroke; | 144 return cee.fStroke == fStroke; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 156 | 156 |
| 157 typedef GrGeometryProcessor INHERITED; | 157 typedef GrGeometryProcessor INHERITED; |
| 158 }; | 158 }; |
| 159 | 159 |
| 160 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect); | 160 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect); |
| 161 | 161 |
| 162 GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, | 162 GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, |
| 163 GrContext* context, | 163 GrContext* context, |
| 164 const GrDrawTargetCaps&, | 164 const GrDrawTargetCaps&, |
| 165 GrTexture* textures[]) { | 165 GrTexture* textures[]) { |
| 166 return CircleEdgeEffect::Create(random->nextBool()); | 166 return CircleEdgeEffect::Create(GrRandomColor(random), random->nextBool()); |
| 167 } | 167 } |
| 168 | 168 |
| 169 /////////////////////////////////////////////////////////////////////////////// | 169 /////////////////////////////////////////////////////////////////////////////// |
| 170 | 170 |
| 171 /** | 171 /** |
| 172 * The output of this effect is a modulation of the input color and coverage for
an axis-aligned | 172 * The output of this effect is a modulation of the input color and coverage for
an axis-aligned |
| 173 * ellipse, specified as a 2D offset from center, and the reciprocals of the out
er and inner radii, | 173 * ellipse, specified as a 2D offset from center, and the reciprocals of the out
er and inner radii, |
| 174 * in both x and y directions. | 174 * in both x and y directions. |
| 175 * | 175 * |
| 176 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. | 176 * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. |
| 177 */ | 177 */ |
| 178 | 178 |
| 179 class EllipseEdgeEffect : public GrGeometryProcessor { | 179 class EllipseEdgeEffect : public GrGeometryProcessor { |
| 180 public: | 180 public: |
| 181 static GrGeometryProcessor* Create(bool stroke) { | 181 static GrGeometryProcessor* Create(GrColor color, bool stroke) { |
| 182 return SkNEW_ARGS(EllipseEdgeEffect, (stroke)); | 182 return SkNEW_ARGS(EllipseEdgeEffect, (color, stroke)); |
| 183 } | 183 } |
| 184 | 184 |
| 185 virtual ~EllipseEdgeEffect() {} | 185 virtual ~EllipseEdgeEffect() {} |
| 186 | 186 |
| 187 virtual const char* name() const SK_OVERRIDE { return "EllipseEdge"; } | 187 virtual const char* name() const SK_OVERRIDE { return "EllipseEdge"; } |
| 188 | 188 |
| 189 const GrAttribute* inPosition() const { return fInPosition; } | 189 const GrAttribute* inPosition() const { return fInPosition; } |
| 190 const GrAttribute* inEllipseOffset() const { return fInEllipseOffset; } | 190 const GrAttribute* inEllipseOffset() const { return fInEllipseOffset; } |
| 191 const GrAttribute* inEllipseRadii() const { return fInEllipseRadii; } | 191 const GrAttribute* inEllipseRadii() const { return fInEllipseRadii; } |
| 192 | 192 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 const GrGLCaps& caps, | 268 const GrGLCaps& caps, |
| 269 GrProcessorKeyBuilder* b) const SK_OVERRIDE { | 269 GrProcessorKeyBuilder* b) const SK_OVERRIDE { |
| 270 GLProcessor::GenKey(*this, bt, caps, b); | 270 GLProcessor::GenKey(*this, bt, caps, b); |
| 271 } | 271 } |
| 272 | 272 |
| 273 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) co
nst SK_OVERRIDE { | 273 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) co
nst SK_OVERRIDE { |
| 274 return SkNEW_ARGS(GLProcessor, (*this, bt)); | 274 return SkNEW_ARGS(GLProcessor, (*this, bt)); |
| 275 } | 275 } |
| 276 | 276 |
| 277 private: | 277 private: |
| 278 EllipseEdgeEffect(bool stroke) { | 278 EllipseEdgeEffect(GrColor color, bool stroke) : INHERITED(color) { |
| 279 this->initClassID<EllipseEdgeEffect>(); | 279 this->initClassID<EllipseEdgeEffect>(); |
| 280 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); | 280 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); |
| 281 fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset", | 281 fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset", |
| 282 kVec2f_GrVertexAtt
ribType)); | 282 kVec2f_GrVertexAtt
ribType)); |
| 283 fInEllipseRadii = &this->addVertexAttrib(GrAttribute("inEllipseRadii", | 283 fInEllipseRadii = &this->addVertexAttrib(GrAttribute("inEllipseRadii", |
| 284 kVec4f_GrVertexAttr
ibType)); | 284 kVec4f_GrVertexAttr
ibType)); |
| 285 fStroke = stroke; | 285 fStroke = stroke; |
| 286 } | 286 } |
| 287 | 287 |
| 288 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { | 288 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 303 | 303 |
| 304 typedef GrGeometryProcessor INHERITED; | 304 typedef GrGeometryProcessor INHERITED; |
| 305 }; | 305 }; |
| 306 | 306 |
| 307 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect); | 307 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect); |
| 308 | 308 |
| 309 GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, | 309 GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, |
| 310 GrContext* context, | 310 GrContext* context, |
| 311 const GrDrawTargetCaps&, | 311 const GrDrawTargetCaps&, |
| 312 GrTexture* textures[]) { | 312 GrTexture* textures[]) { |
| 313 return EllipseEdgeEffect::Create(random->nextBool()); | 313 return EllipseEdgeEffect::Create(GrRandomColor(random), random->nextBool()); |
| 314 } | 314 } |
| 315 | 315 |
| 316 /////////////////////////////////////////////////////////////////////////////// | 316 /////////////////////////////////////////////////////////////////////////////// |
| 317 | 317 |
| 318 /** | 318 /** |
| 319 * The output of this effect is a modulation of the input color and coverage for
an ellipse, | 319 * The output of this effect is a modulation of the input color and coverage for
an ellipse, |
| 320 * specified as a 2D offset from center for both the outer and inner paths (if s
troked). The | 320 * specified as a 2D offset from center for both the outer and inner paths (if s
troked). The |
| 321 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c
orrected by | 321 * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge c
orrected by |
| 322 * using differentials. | 322 * using differentials. |
| 323 * | 323 * |
| 324 * The result is device-independent and can be used with any affine matrix. | 324 * The result is device-independent and can be used with any affine matrix. |
| 325 */ | 325 */ |
| 326 | 326 |
| 327 class DIEllipseEdgeEffect : public GrGeometryProcessor { | 327 class DIEllipseEdgeEffect : public GrGeometryProcessor { |
| 328 public: | 328 public: |
| 329 enum Mode { kStroke = 0, kHairline, kFill }; | 329 enum Mode { kStroke = 0, kHairline, kFill }; |
| 330 | 330 |
| 331 static GrGeometryProcessor* Create(Mode mode) { | 331 static GrGeometryProcessor* Create(GrColor color, Mode mode) { |
| 332 return SkNEW_ARGS(DIEllipseEdgeEffect, (mode)); | 332 return SkNEW_ARGS(DIEllipseEdgeEffect, (color, mode)); |
| 333 } | 333 } |
| 334 | 334 |
| 335 virtual ~DIEllipseEdgeEffect() {} | 335 virtual ~DIEllipseEdgeEffect() {} |
| 336 | 336 |
| 337 virtual const char* name() const SK_OVERRIDE { return "DIEllipseEdge"; } | 337 virtual const char* name() const SK_OVERRIDE { return "DIEllipseEdge"; } |
| 338 | 338 |
| 339 const GrAttribute* inPosition() const { return fInPosition; } | 339 const GrAttribute* inPosition() const { return fInPosition; } |
| 340 const GrAttribute* inEllipseOffsets0() const { return fInEllipseOffsets0; } | 340 const GrAttribute* inEllipseOffsets0() const { return fInEllipseOffsets0; } |
| 341 const GrAttribute* inEllipseOffsets1() const { return fInEllipseOffsets1; } | 341 const GrAttribute* inEllipseOffsets1() const { return fInEllipseOffsets1; } |
| 342 | 342 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 const GrGLCaps& caps, | 433 const GrGLCaps& caps, |
| 434 GrProcessorKeyBuilder* b) const SK_OVERRIDE { | 434 GrProcessorKeyBuilder* b) const SK_OVERRIDE { |
| 435 GLProcessor::GenKey(*this, bt, caps, b); | 435 GLProcessor::GenKey(*this, bt, caps, b); |
| 436 } | 436 } |
| 437 | 437 |
| 438 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) co
nst SK_OVERRIDE { | 438 virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) co
nst SK_OVERRIDE { |
| 439 return SkNEW_ARGS(GLProcessor, (*this, bt)); | 439 return SkNEW_ARGS(GLProcessor, (*this, bt)); |
| 440 } | 440 } |
| 441 | 441 |
| 442 private: | 442 private: |
| 443 DIEllipseEdgeEffect(Mode mode) { | 443 DIEllipseEdgeEffect(GrColor color, Mode mode) : INHERITED(color) { |
| 444 this->initClassID<DIEllipseEdgeEffect>(); | 444 this->initClassID<DIEllipseEdgeEffect>(); |
| 445 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); | 445 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_Gr
VertexAttribType)); |
| 446 fInEllipseOffsets0 = &this->addVertexAttrib(GrAttribute("inEllipseOffset
s0", | 446 fInEllipseOffsets0 = &this->addVertexAttrib(GrAttribute("inEllipseOffset
s0", |
| 447 kVec2f_GrVertexA
ttribType)); | 447 kVec2f_GrVertexA
ttribType)); |
| 448 fInEllipseOffsets1 = &this->addVertexAttrib(GrAttribute("inEllipseOffset
s1", | 448 fInEllipseOffsets1 = &this->addVertexAttrib(GrAttribute("inEllipseOffset
s1", |
| 449 kVec2f_GrVertexA
ttribType)); | 449 kVec2f_GrVertexA
ttribType)); |
| 450 fMode = mode; | 450 fMode = mode; |
| 451 } | 451 } |
| 452 | 452 |
| 453 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { | 453 virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 468 | 468 |
| 469 typedef GrGeometryProcessor INHERITED; | 469 typedef GrGeometryProcessor INHERITED; |
| 470 }; | 470 }; |
| 471 | 471 |
| 472 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect); | 472 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect); |
| 473 | 473 |
| 474 GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random, | 474 GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random, |
| 475 GrContext* context, | 475 GrContext* context, |
| 476 const GrDrawTargetCaps&, | 476 const GrDrawTargetCaps&, |
| 477 GrTexture* textures[]) { | 477 GrTexture* textures[]) { |
| 478 return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); | 478 return DIEllipseEdgeEffect::Create(GrRandomColor(random), (Mode)(random->nex
tRangeU(0,2))); |
| 479 } | 479 } |
| 480 | 480 |
| 481 /////////////////////////////////////////////////////////////////////////////// | 481 /////////////////////////////////////////////////////////////////////////////// |
| 482 | 482 |
| 483 void GrOvalRenderer::reset() { | 483 void GrOvalRenderer::reset() { |
| 484 SkSafeSetNull(fRRectIndexBuffer); | 484 SkSafeSetNull(fRRectIndexBuffer); |
| 485 SkSafeSetNull(fStrokeRRectIndexBuffer); | 485 SkSafeSetNull(fStrokeRRectIndexBuffer); |
| 486 } | 486 } |
| 487 | 487 |
| 488 bool GrOvalRenderer::drawOval(GrDrawTarget* target, | 488 bool GrOvalRenderer::drawOval(GrDrawTarget* target, |
| 489 GrDrawState* drawState, | 489 GrDrawState* drawState, |
| 490 GrColor color, |
| 490 const GrContext* context, | 491 const GrContext* context, |
| 491 bool useAA, | 492 bool useAA, |
| 492 const SkRect& oval, | 493 const SkRect& oval, |
| 493 const SkStrokeRec& stroke) | 494 const SkStrokeRec& stroke) |
| 494 { | 495 { |
| 495 bool useCoverageAA = useAA && | 496 bool useCoverageAA = useAA && |
| 496 !drawState->getRenderTarget()->isMultisampled() && | 497 !drawState->getRenderTarget()->isMultisampled() && |
| 497 drawState->couldApplyCoverage(*target->caps()); | 498 drawState->canUseFracCoveragePrimProc(color, *target->caps()); |
| 498 | 499 |
| 499 if (!useCoverageAA) { | 500 if (!useCoverageAA) { |
| 500 return false; | 501 return false; |
| 501 } | 502 } |
| 502 | 503 |
| 503 const SkMatrix& vm = context->getMatrix(); | 504 const SkMatrix& vm = context->getMatrix(); |
| 504 | 505 |
| 505 // we can draw circles | 506 // we can draw circles |
| 506 if (SkScalarNearlyEqual(oval.width(), oval.height()) | 507 if (SkScalarNearlyEqual(oval.width(), oval.height()) |
| 507 && circle_stays_circle(vm)) { | 508 && circle_stays_circle(vm)) { |
| 508 this->drawCircle(target, drawState, context, useCoverageAA, oval, stroke
); | 509 this->drawCircle(target, drawState, color, context, useCoverageAA, oval,
stroke); |
| 509 // if we have shader derivative support, render as device-independent | 510 // if we have shader derivative support, render as device-independent |
| 510 } else if (target->caps()->shaderDerivativeSupport()) { | 511 } else if (target->caps()->shaderDerivativeSupport()) { |
| 511 return this->drawDIEllipse(target, drawState, context, useCoverageAA, ov
al, stroke); | 512 return this->drawDIEllipse(target, drawState, color, context, useCoverag
eAA, oval, stroke); |
| 512 // otherwise axis-aligned ellipses only | 513 // otherwise axis-aligned ellipses only |
| 513 } else if (vm.rectStaysRect()) { | 514 } else if (vm.rectStaysRect()) { |
| 514 return this->drawEllipse(target, drawState, context, useCoverageAA, oval
, stroke); | 515 return this->drawEllipse(target, drawState, color, context, useCoverageA
A, oval, stroke); |
| 515 } else { | 516 } else { |
| 516 return false; | 517 return false; |
| 517 } | 518 } |
| 518 | 519 |
| 519 return true; | 520 return true; |
| 520 } | 521 } |
| 521 | 522 |
| 522 /////////////////////////////////////////////////////////////////////////////// | 523 /////////////////////////////////////////////////////////////////////////////// |
| 523 | 524 |
| 524 void GrOvalRenderer::drawCircle(GrDrawTarget* target, | 525 void GrOvalRenderer::drawCircle(GrDrawTarget* target, |
| 525 GrDrawState* drawState, | 526 GrDrawState* drawState, |
| 527 GrColor color, |
| 526 const GrContext* context, | 528 const GrContext* context, |
| 527 bool useCoverageAA, | 529 bool useCoverageAA, |
| 528 const SkRect& circle, | 530 const SkRect& circle, |
| 529 const SkStrokeRec& stroke) | 531 const SkStrokeRec& stroke) |
| 530 { | 532 { |
| 531 const SkMatrix& vm = drawState->getViewMatrix(); | 533 const SkMatrix& vm = drawState->getViewMatrix(); |
| 532 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); | 534 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); |
| 533 vm.mapPoints(¢er, 1); | 535 vm.mapPoints(¢er, 1); |
| 534 SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width())); | 536 SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width())); |
| 535 SkScalar strokeWidth = vm.mapRadius(stroke.getWidth()); | 537 SkScalar strokeWidth = vm.mapRadius(stroke.getWidth()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 553 } else { | 555 } else { |
| 554 halfWidth = SkScalarHalf(strokeWidth); | 556 halfWidth = SkScalarHalf(strokeWidth); |
| 555 } | 557 } |
| 556 | 558 |
| 557 outerRadius += halfWidth; | 559 outerRadius += halfWidth; |
| 558 if (isStrokeOnly) { | 560 if (isStrokeOnly) { |
| 559 innerRadius = radius - halfWidth; | 561 innerRadius = radius - halfWidth; |
| 560 } | 562 } |
| 561 } | 563 } |
| 562 | 564 |
| 563 GrGeometryProcessor* gp = CircleEdgeEffect::Create(isStrokeOnly && innerRadi
us > 0); | 565 GrGeometryProcessor* gp = CircleEdgeEffect::Create(color, isStrokeOnly && in
nerRadius > 0); |
| 564 drawState->setGeometryProcessor(gp)->unref(); | 566 drawState->setGeometryProcessor(gp)->unref(); |
| 565 | 567 |
| 566 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); | 568 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); |
| 567 SkASSERT(gp->getVertexStride() == sizeof(CircleVertex)); | 569 SkASSERT(gp->getVertexStride() == sizeof(CircleVertex)); |
| 568 if (!geo.succeeded()) { | 570 if (!geo.succeeded()) { |
| 569 SkDebugf("Failed to get space for vertices!\n"); | 571 SkDebugf("Failed to get space for vertices!\n"); |
| 570 return; | 572 return; |
| 571 } | 573 } |
| 572 | 574 |
| 573 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); | 575 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 | 610 |
| 609 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); | 611 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); |
| 610 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6,
&bounds); | 612 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6,
&bounds); |
| 611 target->resetIndexSource(); | 613 target->resetIndexSource(); |
| 612 } | 614 } |
| 613 | 615 |
| 614 /////////////////////////////////////////////////////////////////////////////// | 616 /////////////////////////////////////////////////////////////////////////////// |
| 615 | 617 |
| 616 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, | 618 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
| 617 GrDrawState* drawState, | 619 GrDrawState* drawState, |
| 620 GrColor color, |
| 618 const GrContext* context, | 621 const GrContext* context, |
| 619 bool useCoverageAA, | 622 bool useCoverageAA, |
| 620 const SkRect& ellipse, | 623 const SkRect& ellipse, |
| 621 const SkStrokeRec& stroke) | 624 const SkStrokeRec& stroke) |
| 622 { | 625 { |
| 623 #ifdef SK_DEBUG | 626 #ifdef SK_DEBUG |
| 624 { | 627 { |
| 625 // we should have checked for this previously | 628 // we should have checked for this previously |
| 626 bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect(); | 629 bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect(); |
| 627 SkASSERT(useCoverageAA && isAxisAlignedEllipse); | 630 SkASSERT(useCoverageAA && isAxisAlignedEllipse); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 | 682 |
| 680 xRadius += scaledStroke.fX; | 683 xRadius += scaledStroke.fX; |
| 681 yRadius += scaledStroke.fY; | 684 yRadius += scaledStroke.fY; |
| 682 } | 685 } |
| 683 | 686 |
| 684 GrDrawState::AutoViewMatrixRestore avmr; | 687 GrDrawState::AutoViewMatrixRestore avmr; |
| 685 if (!avmr.setIdentity(drawState)) { | 688 if (!avmr.setIdentity(drawState)) { |
| 686 return false; | 689 return false; |
| 687 } | 690 } |
| 688 | 691 |
| 689 GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly && | 692 GrGeometryProcessor* gp = EllipseEdgeEffect::Create(color, |
| 693 isStrokeOnly && |
| 690 innerXRadius > 0 && inne
rYRadius > 0); | 694 innerXRadius > 0 && inne
rYRadius > 0); |
| 691 | 695 |
| 692 drawState->setGeometryProcessor(gp)->unref(); | 696 drawState->setGeometryProcessor(gp)->unref(); |
| 693 | 697 |
| 694 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); | 698 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); |
| 695 SkASSERT(gp->getVertexStride() == sizeof(EllipseVertex)); | 699 SkASSERT(gp->getVertexStride() == sizeof(EllipseVertex)); |
| 696 if (!geo.succeeded()) { | 700 if (!geo.succeeded()) { |
| 697 SkDebugf("Failed to get space for vertices!\n"); | 701 SkDebugf("Failed to get space for vertices!\n"); |
| 698 return false; | 702 return false; |
| 699 } | 703 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 | 745 |
| 742 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); | 746 target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer()); |
| 743 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6,
&bounds); | 747 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6,
&bounds); |
| 744 target->resetIndexSource(); | 748 target->resetIndexSource(); |
| 745 | 749 |
| 746 return true; | 750 return true; |
| 747 } | 751 } |
| 748 | 752 |
| 749 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, | 753 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, |
| 750 GrDrawState* drawState, | 754 GrDrawState* drawState, |
| 755 GrColor color, |
| 751 const GrContext* context, | 756 const GrContext* context, |
| 752 bool useCoverageAA, | 757 bool useCoverageAA, |
| 753 const SkRect& ellipse, | 758 const SkRect& ellipse, |
| 754 const SkStrokeRec& stroke) | 759 const SkStrokeRec& stroke) |
| 755 { | 760 { |
| 756 const SkMatrix& vm = drawState->getViewMatrix(); | 761 const SkMatrix& vm = drawState->getViewMatrix(); |
| 757 | 762 |
| 758 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); | 763 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); |
| 759 SkScalar xRadius = SkScalarHalf(ellipse.width()); | 764 SkScalar xRadius = SkScalarHalf(ellipse.width()); |
| 760 SkScalar yRadius = SkScalarHalf(ellipse.height()); | 765 SkScalar yRadius = SkScalarHalf(ellipse.height()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 xRadius += strokeWidth; | 802 xRadius += strokeWidth; |
| 798 yRadius += strokeWidth; | 803 yRadius += strokeWidth; |
| 799 } | 804 } |
| 800 if (DIEllipseEdgeEffect::kStroke == mode) { | 805 if (DIEllipseEdgeEffect::kStroke == mode) { |
| 801 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt
roke : | 806 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt
roke : |
| 802 DIEllipseEdgeEffect::kFi
ll; | 807 DIEllipseEdgeEffect::kFi
ll; |
| 803 } | 808 } |
| 804 SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius); | 809 SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius); |
| 805 SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius); | 810 SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius); |
| 806 | 811 |
| 807 GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode); | 812 GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(color, mode); |
| 808 | 813 |
| 809 drawState->setGeometryProcessor(gp)->unref(); | 814 drawState->setGeometryProcessor(gp)->unref(); |
| 810 | 815 |
| 811 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); | 816 GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); |
| 812 SkASSERT(gp->getVertexStride() == sizeof(DIEllipseVertex)); | 817 SkASSERT(gp->getVertexStride() == sizeof(DIEllipseVertex)); |
| 813 if (!geo.succeeded()) { | 818 if (!geo.succeeded()) { |
| 814 SkDebugf("Failed to get space for vertices!\n"); | 819 SkDebugf("Failed to get space for vertices!\n"); |
| 815 return false; | 820 return false; |
| 816 } | 821 } |
| 817 | 822 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 898 kIndicesPerRRect
, | 903 kIndicesPerRRect
, |
| 899 kNumRRectsInInde
xBuffer, | 904 kNumRRectsInInde
xBuffer, |
| 900 kVertsPerRRect); | 905 kVertsPerRRect); |
| 901 } | 906 } |
| 902 return fRRectIndexBuffer; | 907 return fRRectIndexBuffer; |
| 903 } | 908 } |
| 904 } | 909 } |
| 905 | 910 |
| 906 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, | 911 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, |
| 907 GrDrawState* drawState, | 912 GrDrawState* drawState, |
| 913 GrColor color, |
| 908 GrContext* context, | 914 GrContext* context, |
| 909 bool useAA, | 915 bool useAA, |
| 910 const SkRRect& origOuter, | 916 const SkRRect& origOuter, |
| 911 const SkRRect& origInner) { | 917 const SkRRect& origInner) { |
| 912 bool applyAA = useAA && | 918 bool applyAA = useAA && |
| 913 !drawState->getRenderTarget()->isMultisampled() && | 919 !drawState->getRenderTarget()->isMultisampled() && |
| 914 drawState->couldApplyCoverage(*target->caps()); | 920 drawState->canUseFracCoveragePrimProc(color, *target->caps())
; |
| 915 GrDrawState::AutoRestoreEffects are; | 921 GrDrawState::AutoRestoreEffects are; |
| 916 if (!origInner.isEmpty()) { | 922 if (!origInner.isEmpty()) { |
| 917 SkTCopyOnFirstWrite<SkRRect> inner(origInner); | 923 SkTCopyOnFirstWrite<SkRRect> inner(origInner); |
| 918 if (!context->getMatrix().isIdentity()) { | 924 if (!context->getMatrix().isIdentity()) { |
| 919 if (!origInner.transform(context->getMatrix(), inner.writable())) { | 925 if (!origInner.transform(context->getMatrix(), inner.writable())) { |
| 920 return false; | 926 return false; |
| 921 } | 927 } |
| 922 } | 928 } |
| 923 GrPrimitiveEdgeType edgeType = applyAA ? | 929 GrPrimitiveEdgeType edgeType = applyAA ? |
| 924 kInverseFillAA_GrProcessorEdgeType : | 930 kInverseFillAA_GrProcessorEdgeType : |
| 925 kInverseFillBW_GrProcessorEdgeType; | 931 kInverseFillBW_GrProcessorEdgeType; |
| 932 // TODO this needs to be a geometry processor |
| 926 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); | 933 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); |
| 927 if (NULL == fp) { | 934 if (NULL == fp) { |
| 928 return false; | 935 return false; |
| 929 } | 936 } |
| 930 are.set(drawState); | 937 are.set(drawState); |
| 931 drawState->addCoverageProcessor(fp)->unref(); | 938 drawState->addCoverageProcessor(fp)->unref(); |
| 932 } | 939 } |
| 933 | 940 |
| 934 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); | 941 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); |
| 935 if (this->drawRRect(target, drawState, context, useAA, origOuter, fillRec))
{ | 942 if (this->drawRRect(target, drawState, color, context, useAA, origOuter, fil
lRec)) { |
| 936 return true; | 943 return true; |
| 937 } | 944 } |
| 938 | 945 |
| 939 SkASSERT(!origOuter.isEmpty()); | 946 SkASSERT(!origOuter.isEmpty()); |
| 940 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); | 947 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); |
| 941 if (!context->getMatrix().isIdentity()) { | 948 if (!context->getMatrix().isIdentity()) { |
| 942 if (!origOuter.transform(context->getMatrix(), outer.writable())) { | 949 if (!origOuter.transform(context->getMatrix(), outer.writable())) { |
| 943 return false; | 950 return false; |
| 944 } | 951 } |
| 945 } | 952 } |
| 946 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : | 953 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : |
| 947 kFillBW_GrProcessorEdgeType; | 954 kFillBW_GrProcessorEdgeType; |
| 948 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); | 955 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); |
| 949 if (NULL == effect) { | 956 if (NULL == effect) { |
| 950 return false; | 957 return false; |
| 951 } | 958 } |
| 952 if (!are.isSet()) { | 959 if (!are.isSet()) { |
| 953 are.set(drawState); | 960 are.set(drawState); |
| 954 } | 961 } |
| 955 GrDrawState::AutoViewMatrixRestore avmr; | 962 GrDrawState::AutoViewMatrixRestore avmr; |
| 956 if (!avmr.setIdentity(drawState)) { | 963 if (!avmr.setIdentity(drawState)) { |
| 957 return false; | 964 return false; |
| 958 } | 965 } |
| 959 drawState->addCoverageProcessor(effect)->unref(); | 966 drawState->addCoverageProcessor(effect)->unref(); |
| 960 SkRect bounds = outer->getBounds(); | 967 SkRect bounds = outer->getBounds(); |
| 961 if (applyAA) { | 968 if (applyAA) { |
| 962 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); | 969 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
| 963 } | 970 } |
| 964 target->drawRect(drawState, bounds, NULL, NULL); | 971 target->drawRect(drawState, color, bounds, NULL, NULL); |
| 965 return true; | 972 return true; |
| 966 } | 973 } |
| 967 | 974 |
| 968 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, | 975 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| 969 GrDrawState* drawState, | 976 GrDrawState* drawState, |
| 977 GrColor color, |
| 970 GrContext* context, | 978 GrContext* context, |
| 971 bool useAA, | 979 bool useAA, |
| 972 const SkRRect& rrect, | 980 const SkRRect& rrect, |
| 973 const SkStrokeRec& stroke) { | 981 const SkStrokeRec& stroke) { |
| 974 if (rrect.isOval()) { | 982 if (rrect.isOval()) { |
| 975 return this->drawOval(target, drawState, context, useAA, rrect.getBounds
(), stroke); | 983 return this->drawOval(target, drawState, color, context, useAA, rrect.ge
tBounds(), stroke); |
| 976 } | 984 } |
| 977 | 985 |
| 978 bool useCoverageAA = useAA && | 986 bool useCoverageAA = useAA && |
| 979 !drawState->getRenderTarget()->isMultisampled() && | 987 !drawState->getRenderTarget()->isMultisampled() && |
| 980 drawState->couldApplyCoverage(*target->caps()); | 988 drawState->canUseFracCoveragePrimProc(color, *target->caps()); |
| 981 | 989 |
| 982 // only anti-aliased rrects for now | 990 // only anti-aliased rrects for now |
| 983 if (!useCoverageAA) { | 991 if (!useCoverageAA) { |
| 984 return false; | 992 return false; |
| 985 } | 993 } |
| 986 | 994 |
| 987 const SkMatrix& vm = context->getMatrix(); | 995 const SkMatrix& vm = context->getMatrix(); |
| 988 | 996 |
| 989 if (!vm.rectStaysRect() || !rrect.isSimple()) { | 997 if (!vm.rectStaysRect() || !rrect.isSimple()) { |
| 990 return false; | 998 return false; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 | 1070 |
| 1063 if (isStrokeOnly) { | 1071 if (isStrokeOnly) { |
| 1064 innerRadius = xRadius - halfWidth; | 1072 innerRadius = xRadius - halfWidth; |
| 1065 } | 1073 } |
| 1066 outerRadius += halfWidth; | 1074 outerRadius += halfWidth; |
| 1067 bounds.outset(halfWidth, halfWidth); | 1075 bounds.outset(halfWidth, halfWidth); |
| 1068 } | 1076 } |
| 1069 | 1077 |
| 1070 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); | 1078 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); |
| 1071 | 1079 |
| 1072 GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly); | 1080 GrGeometryProcessor* effect = CircleEdgeEffect::Create(color, isStrokeOn
ly); |
| 1073 drawState->setGeometryProcessor(effect)->unref(); | 1081 drawState->setGeometryProcessor(effect)->unref(); |
| 1074 | 1082 |
| 1075 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid
e(), 0); | 1083 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid
e(), 0); |
| 1076 SkASSERT(effect->getVertexStride() == sizeof(CircleVertex)); | 1084 SkASSERT(effect->getVertexStride() == sizeof(CircleVertex)); |
| 1077 if (!geo.succeeded()) { | 1085 if (!geo.succeeded()) { |
| 1078 SkDebugf("Failed to get space for vertices!\n"); | 1086 SkDebugf("Failed to get space for vertices!\n"); |
| 1079 return false; | 1087 return false; |
| 1080 } | 1088 } |
| 1081 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); | 1089 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); |
| 1082 | 1090 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1164 innerYRadius = yRadius - scaledStroke.fY; | 1172 innerYRadius = yRadius - scaledStroke.fY; |
| 1165 } | 1173 } |
| 1166 | 1174 |
| 1167 xRadius += scaledStroke.fX; | 1175 xRadius += scaledStroke.fX; |
| 1168 yRadius += scaledStroke.fY; | 1176 yRadius += scaledStroke.fY; |
| 1169 bounds.outset(scaledStroke.fX, scaledStroke.fY); | 1177 bounds.outset(scaledStroke.fX, scaledStroke.fY); |
| 1170 } | 1178 } |
| 1171 | 1179 |
| 1172 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); | 1180 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); |
| 1173 | 1181 |
| 1174 GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly); | 1182 GrGeometryProcessor* effect = EllipseEdgeEffect::Create(color, isStrokeO
nly); |
| 1175 drawState->setGeometryProcessor(effect)->unref(); | 1183 drawState->setGeometryProcessor(effect)->unref(); |
| 1176 | 1184 |
| 1177 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid
e(), 0); | 1185 GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStrid
e(), 0); |
| 1178 SkASSERT(effect->getVertexStride() == sizeof(EllipseVertex)); | 1186 SkASSERT(effect->getVertexStride() == sizeof(EllipseVertex)); |
| 1179 if (!geo.succeeded()) { | 1187 if (!geo.succeeded()) { |
| 1180 SkDebugf("Failed to get space for vertices!\n"); | 1188 SkDebugf("Failed to get space for vertices!\n"); |
| 1181 return false; | 1189 return false; |
| 1182 } | 1190 } |
| 1183 | 1191 |
| 1184 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | 1192 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : | 1247 int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 : |
| 1240 SK_ARRAY_COUNT(gRRectIndices); | 1248 SK_ARRAY_COUNT(gRRectIndices); |
| 1241 target->setIndexSourceToBuffer(indexBuffer); | 1249 target->setIndexSourceToBuffer(indexBuffer); |
| 1242 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1
6, indexCnt, | 1250 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 1
6, indexCnt, |
| 1243 &bounds); | 1251 &bounds); |
| 1244 } | 1252 } |
| 1245 | 1253 |
| 1246 target->resetIndexSource(); | 1254 target->resetIndexSource(); |
| 1247 return true; | 1255 return true; |
| 1248 } | 1256 } |
| OLD | NEW |