|
|
Created:
6 years, 9 months ago by bsalomon Modified:
6 years, 9 months ago CC:
skia-review_googlegroups.com Base URL:
https://skia.googlecode.com/svn/trunk Visibility:
Public. |
DescriptionAdd effect-based clip for nine-patch SkRRects.
BUG=skia:2181
Committed: http://code.google.com/p/skia/source/detail?r=13794
Patch Set 1 #
Total comments: 6
Patch Set 2 : rebase #Patch Set 3 : rebase #Patch Set 4 : rebase again #
Messages
Total messages: 13 (0 generated)
Builds upon (and fixes a few nits) in: https://codereview.chromium.org/194603004/
lgtm + comments https://codereview.chromium.org/194703011/diff/1/src/gpu/effects/GrRRectEffec... File src/gpu/effects/GrRRectEffect.cpp (right): https://codereview.chromium.org/194703011/diff/1/src/gpu/effects/GrRRectEffec... src/gpu/effects/GrRRectEffect.cpp:382: kNinePatch_RRectType, This might be worth adding to SkRRect. https://codereview.chromium.org/194703011/diff/1/src/gpu/effects/GrRRectEffec... src/gpu/effects/GrRRectEffect.cpp:616: uman.set2f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX), Use SkScalarInvert or SkScalarFastInvert? https://codereview.chromium.org/194703011/diff/1/src/gpu/effects/GrRRectEffec... src/gpu/effects/GrRRectEffect.cpp:671: cornerFlags = -1; This seems a little hacky, but I don't have a better suggestion.
https://codereview.chromium.org/194703011/diff/1/src/gpu/effects/GrRRectEffec... File src/gpu/effects/GrRRectEffect.cpp (right): https://codereview.chromium.org/194703011/diff/1/src/gpu/effects/GrRRectEffec... src/gpu/effects/GrRRectEffect.cpp:382: kNinePatch_RRectType, On 2014/03/12 13:37:55, JimVV wrote: > This might be worth adding to SkRRect. Will do in follow-up CL https://codereview.chromium.org/194703011/diff/1/src/gpu/effects/GrRRectEffec... src/gpu/effects/GrRRectEffect.cpp:616: uman.set2f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX), On 2014/03/12 13:37:55, JimVV wrote: > Use SkScalarInvert or SkScalarFastInvert? I checked with Mike and he sez using SkScalarInvert doesn't add any value (now that we no longer support scalar=fixed) https://codereview.chromium.org/194703011/diff/1/src/gpu/effects/GrRRectEffec... src/gpu/effects/GrRRectEffect.cpp:671: cornerFlags = -1; On 2014/03/12 13:37:55, JimVV wrote: > This seems a little hacky, but I don't have a better suggestion. yup :)
The CQ bit was checked by bsalomon@google.com
CQ is trying da patch. Follow status at https://skia-tree-status.appspot.com/cq/bsalomon@google.com/194703011/30001
The CQ bit was unchecked by rmistry@google.com
The CQ bit was checked by rmistry@google.com
CQ is trying da patch. Follow status at https://skia-tree-status.appspot.com/cq/bsalomon@google.com/194703011/30001
The CQ bit was unchecked by commit-bot@chromium.org
Failed to apply patch for src/gpu/effects/GrRRectEffect.cpp: While running patch -p1 --forward --force --no-backup-if-mismatch; patching file src/gpu/effects/GrRRectEffect.cpp Hunk #5 FAILED at 460. 1 out of 13 hunks FAILED -- saving rejects to file src/gpu/effects/GrRRectEffect.cpp.rej Patch: src/gpu/effects/GrRRectEffect.cpp Index: src/gpu/effects/GrRRectEffect.cpp diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp index 636730db221b62cc291dcb70c8c38e94424ca40a..324d02da02df5c140aec42a9a98c5e0607535cc5 100644 --- a/src/gpu/effects/GrRRectEffect.cpp +++ b/src/gpu/effects/GrRRectEffect.cpp @@ -375,22 +375,27 @@ void GLCircularRRectEffect::setData(const GrGLUniformManager& uman, class GLEllipticalRRectEffect; -/** - * Currently this effect only supports "simple" elliptical round rects (i.e. - * the corners all have a common x/y radii pair). - */ class EllipticalRRectEffect : public GrEffect { public: - // This effect only supports rrects where the radii are >= kRadiusMin + // This effect currently works for these two classifications of SkRRects + enum RRectType { + kSimple_RRectType, // SkRRect::kSimple_Type + kNinePatch_RRectType, // The two left x radii are the same, the two + // top y radii are the same, etc. + }; + + // This effect only supports rrects where the radii are >= kRadiusMin. static const SkScalar kRadiusMin; - static GrEffectRef* Create(GrEffectEdgeType, const SkRRect&); + static GrEffectRef* Create(GrEffectEdgeType, RRectType, const SkRRect&); virtual ~EllipticalRRectEffect() {}; static const char* Name() { return "EllipticalRRect"; } const SkRRect& getRRect() const { return fRRect; } + RRectType getRRectType() const { return fRRectType; } + GrEffectEdgeType getEdgeType() const { return fEdgeType; } typedef GLEllipticalRRectEffect GLEffect; @@ -400,11 +405,12 @@ public: virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; private: - EllipticalRRectEffect(GrEffectEdgeType, const SkRRect&); + EllipticalRRectEffect(GrEffectEdgeType, RRectType, const SkRRect&); virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; SkRRect fRRect; + RRectType fRRectType; GrEffectEdgeType fEdgeType; GR_DECLARE_EFFECT_TEST; @@ -415,9 +421,11 @@ private: const SkScalar EllipticalRRectEffect::kRadiusMin = 0.5f; GrEffectRef* EllipticalRRectEffect::Create(GrEffectEdgeType edgeType, + RRectType rrType, const SkRRect& rrect) { -// SkASSERT(kFillAA_GrEffectEdgeType == edgeType || kInverseFillAA_GrEffectEdgeType == edgeType); - return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrect)))); + SkASSERT(kFillAA_GrEffectEdgeType == edgeType || kInverseFillAA_GrEffectEdgeType == edgeType); + return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrType, + rrect)))); } void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { @@ -428,14 +436,17 @@ const GrBackendEffectFactory& EllipticalRRectEffect::getFactory() const { return GrTBackendEffectFactory<EllipticalRRectEffect>::getInstance(); } -EllipticalRRectEffect::EllipticalRRectEffect(GrEffectEdgeType edgeType, const SkRRect& rrect) +EllipticalRRectEffect::EllipticalRRectEffect(GrEffectEdgeType edgeType, RRectType rrType, + const SkRRect& rrect) : fRRect(rrect) + , fRRectType(rrType) , fEdgeType(edgeType){ this->setWillReadFragmentPosition(); } bool EllipticalRRectEffect::onIsEqual(const GrEffect& other) const { const EllipticalRRectEffect& erre = CastEffect<EllipticalRRectEffect>(other); + // No need to check fRRectType as it is derived from fRRect. return fEdgeType == erre.fEdgeType && fRRect == erre.fRRect; } @@ -449,15 +460,34 @@ GrEffectRef* EllipticalRRectEffect::TestCreate(SkRandom* random, GrTexture*[]) { SkScalar w = random->nextRangeScalar(20.f, 1000.f); SkScalar h = random->nextRangeScalar(20.f, 1000.f); - SkScalar rx = random->nextRangeF(kRadiusMin, 9.f); - SkScalar ry = random->nextRangeF(kRadiusMin, 9.f); + SkVector r[4]; + r[SkRRect::kUpperLeft_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); + // ensure at least one corner really is elliptical + do { + r[SkRRect::kUpperLeft_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); + } while (r[SkRRect::kUpperLeft_Corner].fY == r[SkRRect::kUpperLeft_Corner].fX); + SkRRect rrect; - rrect.setRectXY(SkRect::MakeWH(w, h), rx, ry); + if (random->nextBool()) { + // half the time create a four-radii rrect. + r[SkRRect::kLowerRight_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); + r[SkRRect::kLowerRight_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); + + r[SkRRect::kUpperRight_Corner].fX = r[SkRRect::kLowerRight_Corner].fX; + r[SkRRect::kUpperRight_Corner].fY = r[SkRRect::kUpperLeft_Corner].fY; + + r[SkRRect::kLowerLeft_Corner].fX = r[SkRRect::kUpperLeft_Corner].fX; + r[SkRRect::kLowerLeft_Corner].fY = r[SkRRect::kLowerRight_Corner].fY; + + rrect.setRectRadii(SkRect::MakeWH(w, h), r); + } else { + rrect.setRectXY(SkRect::MakeWH(w, h), r[SkRRect::kUpperLeft_Corner].fX, + r[SkRRect::kUpperLeft_Corner].fY); + } GrEffectRef* effect; do { - GrEffectEdgeType et = random->nextBool() ? kFillAA_GrEffectEdgeType : - kInverseFillAA_GrEffectEdgeType; - effect = EllipticalRRectEffect::Create(et, rrect); + GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectEdgeTypeCnt); + effect = GrRRectEffect::Create(et, rrect); } while (NULL == effect); return effect; } @@ -482,7 +512,7 @@ public: private: GrGLUniformManager::UniformHandle fInnerRectUniform; - GrGLUniformManager::UniformHandle fInvRadiusXYSqdUniform; + GrGLUniformManager::UniformHandle fInvRadiiSqdUniform; SkRRect fPrevRRect; typedef GrGLEffect INHERITED; }; @@ -502,16 +532,11 @@ void GLEllipticalRRectEffect::emitCode(GrGLShaderBuilder* builder, const TextureSamplerArray& samplers) { const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEffect>(); const char *rectName; - const char *invRadiusXYSqdName; // The inner rect is the rrect bounds inset by the x/y radii fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "innerRect", &rectName); - fInvRadiusXYSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, - kVec2f_GrSLType, - "invRadiusXY", - &invRadiusXYSqdName); const char* fragmentPos = builder->fragmentPosition(); // At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos // to the ellipse center. The vector is pinned in x and y to be in the quarter-plane relevant @@ -526,9 +551,33 @@ void GLEllipticalRRectEffect::emitCode(GrGLShaderBuilder* builder, // need be computed to determine the min alpha. builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName); - builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n"); - // Z is the x/y offsets divided by squared radii. - builder->fsCodeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiusXYSqdName); + switch (erre.getRRectType()) { + case EllipticalRRectEffect::kSimple_RRectType: { + const char *invRadiiXYSqdName; + fInvRadiiSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kVec2f_GrSLType, + "invRadiiXY", + &invRadiiXYSqdName); + builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n"); + // Z is the x/y offsets divided by squared radii. + builder->fsCodeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName); + break; + } + case EllipticalRRectEffect::kNinePatch_RRectType: { + const char *invRadiiLTRBSqdName; + fInvRadiiSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kVec4f_GrSLType, + "invRadiiLTRB", + &invRadiiLTRBSqdName); + builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n"); + // Z is the x/y offsets divided by squared radii. We only care about the (at most) one + // corner where both the x and y offsets are positive, hence the maxes. (The inverse + // squared radii will always be positive.) + builder->fsCodeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);\n", + invRadiiLTRBSqdName, invRadiiLTRBSqdName); + break; + } + } // implicit is the evaluation of (x/a)^2 + (y/b)^2 … (message too large)
The CQ bit was checked by bsalomon@google.com
CQ is trying da patch. Follow status at https://skia-tree-status.appspot.com/cq/bsalomon@google.com/194703011/50001
Message was sent while issue was closed.
Change committed as 13794 |