| 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 "GrEffect.h" | 10 #include "GrEffect.h" |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 const char* inputColor, | 355 const char* inputColor, |
| 356 const TextureSamplerArray& samplers) SK_OVERRIDE { | 356 const TextureSamplerArray& samplers) SK_OVERRIDE { |
| 357 GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertex
Builder(); | 357 GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertex
Builder(); |
| 358 SkASSERT(NULL != vertexBuilder); | 358 SkASSERT(NULL != vertexBuilder); |
| 359 | 359 |
| 360 const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIE
llipseEdgeEffect>(); | 360 const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIE
llipseEdgeEffect>(); |
| 361 | 361 |
| 362 SkAssertResult(builder->enableFeature( | 362 SkAssertResult(builder->enableFeature( |
| 363 GrGLShaderBuilder::kStandardDeriva
tives_GLSLFeature)); | 363 GrGLShaderBuilder::kStandardDeriva
tives_GLSLFeature)); |
| 364 | 364 |
| 365 const char *vsOffsetName, *fsOffsetName; | 365 const char *vsOffsetName0, *fsOffsetName0; |
| 366 vertexBuilder->addVarying(kVec4f_GrSLType, "EllipseOffsets", | 366 vertexBuilder->addVarying(kVec2f_GrSLType, "EllipseOffsets0", |
| 367 &vsOffsetName, &fsOffsetName); | 367 &vsOffsetName0, &fsOffsetName0); |
| 368 const SkString* attr0Name = | 368 const SkString* attr0Name = |
| 369 vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttrib
Indices()[0]); | 369 vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttrib
Indices()[0]); |
| 370 vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name
->c_str()); | 370 vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName0, attr0Nam
e->c_str()); |
| 371 const char *vsOffsetName1, *fsOffsetName1; |
| 372 vertexBuilder->addVarying(kVec2f_GrSLType, "EllipseOffsets1", |
| 373 &vsOffsetName1, &fsOffsetName1); |
| 374 const SkString* attr1Name = |
| 375 vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttrib
Indices()[1]); |
| 376 vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName1, attr1Nam
e->c_str()); |
| 371 | 377 |
| 372 // for outer curve | 378 // for outer curve |
| 373 builder->fsCodeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetNam
e); | 379 builder->fsCodeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetNam
e0); |
| 374 builder->fsCodeAppend("\tfloat test = dot(scaledOffset, scaledOffset
) - 1.0;\n"); | 380 builder->fsCodeAppend("\tfloat test = dot(scaledOffset, scaledOffset
) - 1.0;\n"); |
| 375 builder->fsCodeAppendf("\tvec4 duvdx = dFdx(%s);\n", fsOffsetName); | 381 builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0); |
| 376 builder->fsCodeAppendf("\tvec4 duvdy = dFdy(%s);\n", fsOffsetName); | 382 builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0); |
| 377 builder->fsCodeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s
.y*duvdx.y,\n" | 383 builder->fsCodeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s
.y*duvdx.y,\n" |
| 378 "\t 2.0*%s.x*duvdy.x + 2.0*%s
.y*duvdy.y);\n", | 384 "\t 2.0*%s.x*duvdy.x + 2.0*%s
.y*duvdy.y);\n", |
| 379 fsOffsetName, fsOffsetName, fsOffsetName, fsO
ffsetName); | 385 fsOffsetName0, fsOffsetName0, fsOffsetName0,
fsOffsetName0); |
| 380 | 386 |
| 381 builder->fsCodeAppend("\tfloat grad_dot = dot(grad, grad);\n"); | 387 builder->fsCodeAppend("\tfloat grad_dot = dot(grad, grad);\n"); |
| 382 // we need to clamp the length^2 of the gradiant vector to a non-zer
o value, because | 388 // we need to clamp the length^2 of the gradiant vector to a non-zer
o value, because |
| 383 // on the Nexus 4 the undefined result of inversesqrt(0) drops out a
n entire tile | 389 // on the Nexus 4 the undefined result of inversesqrt(0) drops out a
n entire tile |
| 384 // TODO: restrict this to Adreno-only | 390 // TODO: restrict this to Adreno-only |
| 385 builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n"); | 391 builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n"); |
| 386 builder->fsCodeAppend("\tfloat invlen = inversesqrt(grad_dot);\n"); | 392 builder->fsCodeAppend("\tfloat invlen = inversesqrt(grad_dot);\n"); |
| 387 if (kHairline == ellipseEffect.getMode()) { | 393 if (kHairline == ellipseEffect.getMode()) { |
| 388 // can probably do this with one step | 394 // can probably do this with one step |
| 389 builder->fsCodeAppend("\tfloat edgeAlpha = clamp(1.0-test*invlen
, 0.0, 1.0);\n"); | 395 builder->fsCodeAppend("\tfloat edgeAlpha = clamp(1.0-test*invlen
, 0.0, 1.0);\n"); |
| 390 builder->fsCodeAppend("\tedgeAlpha *= clamp(1.0+test*invlen, 0.0
, 1.0);\n"); | 396 builder->fsCodeAppend("\tedgeAlpha *= clamp(1.0+test*invlen, 0.0
, 1.0);\n"); |
| 391 } else { | 397 } else { |
| 392 builder->fsCodeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen
, 0.0, 1.0);\n"); | 398 builder->fsCodeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen
, 0.0, 1.0);\n"); |
| 393 } | 399 } |
| 394 | 400 |
| 395 // for inner curve | 401 // for inner curve |
| 396 if (kStroke == ellipseEffect.getMode()) { | 402 if (kStroke == ellipseEffect.getMode()) { |
| 397 builder->fsCodeAppendf("\tscaledOffset = %s.zw;\n", fsOffsetName
); | 403 builder->fsCodeAppendf("\tscaledOffset = %s.xy;\n", fsOffsetName
1); |
| 398 builder->fsCodeAppend("\ttest = dot(scaledOffset, scaledOffset)
- 1.0;\n"); | 404 builder->fsCodeAppend("\ttest = dot(scaledOffset, scaledOffset)
- 1.0;\n"); |
| 399 builder->fsCodeAppendf("\tgrad = vec2(2.0*%s.z*duvdx.z + 2.0*%s.
w*duvdx.w,\n" | 405 builder->fsCodeAppendf("\tduvdx = dFdx(%s);\n", fsOffsetName1); |
| 400 "\t 2.0*%s.z*duvdy.z + 2.0*%s.
w*duvdy.w);\n", | 406 builder->fsCodeAppendf("\tduvdy = dFdy(%s);\n", fsOffsetName1); |
| 401 fsOffsetName, fsOffsetName, fsOffsetName,
fsOffsetName); | 407 builder->fsCodeAppendf("\tgrad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.
y*duvdx.y,\n" |
| 408 "\t 2.0*%s.x*duvdy.x + 2.0*%s.
y*duvdy.y);\n", |
| 409 fsOffsetName1, fsOffsetName1, fsOffsetNam
e1, fsOffsetName1); |
| 402 builder->fsCodeAppend("\tinvlen = inversesqrt(dot(grad, grad));\
n"); | 410 builder->fsCodeAppend("\tinvlen = inversesqrt(dot(grad, grad));\
n"); |
| 403 builder->fsCodeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0
, 1.0);\n"); | 411 builder->fsCodeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0
, 1.0);\n"); |
| 404 } | 412 } |
| 405 | 413 |
| 406 SkString modulate; | 414 SkString modulate; |
| 407 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha"); | 415 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha"); |
| 408 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()
); | 416 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()
); |
| 409 } | 417 } |
| 410 | 418 |
| 411 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG
LCaps&) { | 419 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG
LCaps&) { |
| 412 const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIE
llipseEdgeEffect>(); | 420 const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIE
llipseEdgeEffect>(); |
| 413 | 421 |
| 414 return ellipseEffect.getMode(); | 422 return ellipseEffect.getMode(); |
| 415 } | 423 } |
| 416 | 424 |
| 417 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_
OVERRIDE { | 425 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_
OVERRIDE { |
| 418 } | 426 } |
| 419 | 427 |
| 420 private: | 428 private: |
| 421 typedef GrGLEffect INHERITED; | 429 typedef GrGLEffect INHERITED; |
| 422 }; | 430 }; |
| 423 | 431 |
| 424 private: | 432 private: |
| 425 DIEllipseEdgeEffect(Mode mode) : GrEffect() { | 433 DIEllipseEdgeEffect(Mode mode) : GrEffect() { |
| 426 this->addVertexAttrib(kVec4f_GrSLType); | 434 this->addVertexAttrib(kVec2f_GrSLType); |
| 435 this->addVertexAttrib(kVec2f_GrSLType); |
| 427 fMode = mode; | 436 fMode = mode; |
| 428 } | 437 } |
| 429 | 438 |
| 430 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | 439 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { |
| 431 const DIEllipseEdgeEffect& eee = CastEffect<DIEllipseEdgeEffect>(other); | 440 const DIEllipseEdgeEffect& eee = CastEffect<DIEllipseEdgeEffect>(other); |
| 432 return eee.fMode == fMode; | 441 return eee.fMode == fMode; |
| 433 } | 442 } |
| 434 | 443 |
| 435 Mode fMode; | 444 Mode fMode; |
| 436 | 445 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 // position + offset + 1/radii | 591 // position + offset + 1/radii |
| 583 extern const GrVertexAttrib gEllipseVertexAttribs[] = { | 592 extern const GrVertexAttrib gEllipseVertexAttribs[] = { |
| 584 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, | 593 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, |
| 585 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding
}, | 594 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding
}, |
| 586 {kVec4f_GrVertexAttribType, 2*sizeof(GrPoint), kEffect_GrVertexAttribBinding
} | 595 {kVec4f_GrVertexAttribType, 2*sizeof(GrPoint), kEffect_GrVertexAttribBinding
} |
| 587 }; | 596 }; |
| 588 | 597 |
| 589 // position + offsets | 598 // position + offsets |
| 590 extern const GrVertexAttrib gDIEllipseVertexAttribs[] = { | 599 extern const GrVertexAttrib gDIEllipseVertexAttribs[] = { |
| 591 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, | 600 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi
ng}, |
| 592 {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding
}, | 601 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding
}, |
| 602 {kVec2f_GrVertexAttribType, 2*sizeof(GrPoint), kEffect_GrVertexAttribBinding
}, |
| 593 }; | 603 }; |
| 594 | 604 |
| 595 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, | 605 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
| 596 bool useAA, | 606 bool useAA, |
| 597 const SkRect& ellipse, | 607 const SkRect& ellipse, |
| 598 const SkStrokeRec& stroke) | 608 const SkStrokeRec& stroke) |
| 599 { | 609 { |
| 600 GrDrawState* drawState = target->drawState(); | 610 GrDrawState* drawState = target->drawState(); |
| 601 #ifdef SK_DEBUG | 611 #ifdef SK_DEBUG |
| 602 { | 612 { |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 } | 1137 } |
| 1128 | 1138 |
| 1129 // drop out the middle quad if we're stroked | 1139 // drop out the middle quad if we're stroked |
| 1130 int indexCnt = isStroked ? GR_ARRAY_COUNT(gRRectIndices)-6 : GR_ARRAY_CO
UNT(gRRectIndices); | 1140 int indexCnt = isStroked ? GR_ARRAY_COUNT(gRRectIndices)-6 : GR_ARRAY_CO
UNT(gRRectIndices); |
| 1131 target->setIndexSourceToBuffer(indexBuffer); | 1141 target->setIndexSourceToBuffer(indexBuffer); |
| 1132 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou
nds); | 1142 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bou
nds); |
| 1133 } | 1143 } |
| 1134 | 1144 |
| 1135 return true; | 1145 return true; |
| 1136 } | 1146 } |
| OLD | NEW |