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 |