| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "gl/builders/GrGLProgramBuilder.h" | 8 #include "gl/builders/GrGLProgramBuilder.h" |
| 9 #include "GrRRectEffect.h" | 9 #include "GrRRectEffect.h" |
| 10 | 10 |
| 11 #include "gl/GrGLEffect.h" | 11 #include "gl/GrGLProcessor.h" |
| 12 #include "gl/GrGLSL.h" | 12 #include "gl/GrGLSL.h" |
| 13 #include "GrConvexPolyEffect.h" | 13 #include "GrConvexPolyEffect.h" |
| 14 #include "GrOvalEffect.h" | 14 #include "GrOvalEffect.h" |
| 15 #include "GrTBackendEffectFactory.h" | 15 #include "GrTBackendProcessorFactory.h" |
| 16 | 16 |
| 17 #include "SkRRect.h" | 17 #include "SkRRect.h" |
| 18 | 18 |
| 19 // The effects defined here only handle rrect radii >= kRadiusMin. | 19 // The effects defined here only handle rrect radii >= kRadiusMin. |
| 20 static const SkScalar kRadiusMin = SK_ScalarHalf; | 20 static const SkScalar kRadiusMin = SK_ScalarHalf; |
| 21 | 21 |
| 22 ////////////////////////////////////////////////////////////////////////////// | 22 ////////////////////////////////////////////////////////////////////////////// |
| 23 | 23 |
| 24 class GLCircularRRectEffect; | 24 class GLCircularRRectEffect; |
| 25 | 25 |
| 26 class CircularRRectEffect : public GrEffect { | 26 class CircularRRectEffect : public GrFragmentProcessor { |
| 27 public: | 27 public: |
| 28 | 28 |
| 29 enum CornerFlags { | 29 enum CornerFlags { |
| 30 kTopLeft_CornerFlag = (1 << SkRRect::kUpperLeft_Corner), | 30 kTopLeft_CornerFlag = (1 << SkRRect::kUpperLeft_Corner), |
| 31 kTopRight_CornerFlag = (1 << SkRRect::kUpperRight_Corner), | 31 kTopRight_CornerFlag = (1 << SkRRect::kUpperRight_Corner), |
| 32 kBottomRight_CornerFlag = (1 << SkRRect::kLowerRight_Corner), | 32 kBottomRight_CornerFlag = (1 << SkRRect::kLowerRight_Corner), |
| 33 kBottomLeft_CornerFlag = (1 << SkRRect::kLowerLeft_Corner), | 33 kBottomLeft_CornerFlag = (1 << SkRRect::kLowerLeft_Corner), |
| 34 | 34 |
| 35 kLeft_CornerFlags = kTopLeft_CornerFlag | kBottomLeft_CornerFlag, | 35 kLeft_CornerFlags = kTopLeft_CornerFlag | kBottomLeft_CornerFlag, |
| 36 kTop_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag, | 36 kTop_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag, |
| 37 kRight_CornerFlags = kTopRight_CornerFlag | kBottomRight_CornerFlag, | 37 kRight_CornerFlags = kTopRight_CornerFlag | kBottomRight_CornerFlag, |
| 38 kBottom_CornerFlags = kBottomLeft_CornerFlag | kBottomRight_CornerFlag, | 38 kBottom_CornerFlags = kBottomLeft_CornerFlag | kBottomRight_CornerFlag, |
| 39 | 39 |
| 40 kAll_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag | | 40 kAll_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag | |
| 41 kBottomLeft_CornerFlag | kBottomRight_CornerFlag, | 41 kBottomLeft_CornerFlag | kBottomRight_CornerFlag, |
| 42 | 42 |
| 43 kNone_CornerFlags = 0 | 43 kNone_CornerFlags = 0 |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 // The flags are used to indicate which corners are circluar (unflagged corn
ers are assumed to | 46 // The flags are used to indicate which corners are circluar (unflagged corn
ers are assumed to |
| 47 // be square). | 47 // be square). |
| 48 static GrEffect* Create(GrEffectEdgeType, uint32_t circularCornerFlags, cons
t SkRRect&); | 48 static GrFragmentProcessor* Create(GrPrimitiveEdgeType, uint32_t circularCor
nerFlags, |
| 49 const SkRRect&); |
| 49 | 50 |
| 50 virtual ~CircularRRectEffect() {}; | 51 virtual ~CircularRRectEffect() {}; |
| 51 static const char* Name() { return "CircularRRect"; } | 52 static const char* Name() { return "CircularRRect"; } |
| 52 | 53 |
| 53 const SkRRect& getRRect() const { return fRRect; } | 54 const SkRRect& getRRect() const { return fRRect; } |
| 54 | 55 |
| 55 uint32_t getCircularCornerFlags() const { return fCircularCornerFlags; } | 56 uint32_t getCircularCornerFlags() const { return fCircularCornerFlags; } |
| 56 | 57 |
| 57 GrEffectEdgeType getEdgeType() const { return fEdgeType; } | 58 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } |
| 58 | 59 |
| 59 typedef GLCircularRRectEffect GLEffect; | 60 typedef GLCircularRRectEffect GLProcessor; |
| 60 | 61 |
| 61 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 62 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
| 62 | 63 |
| 63 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 64 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR
IDE; |
| 64 | 65 |
| 65 private: | 66 private: |
| 66 CircularRRectEffect(GrEffectEdgeType, uint32_t circularCornerFlags, const Sk
RRect&); | 67 CircularRRectEffect(GrPrimitiveEdgeType, uint32_t circularCornerFlags, const
SkRRect&); |
| 67 | 68 |
| 68 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; | 69 virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; |
| 69 | 70 |
| 70 SkRRect fRRect; | 71 SkRRect fRRect; |
| 71 GrEffectEdgeType fEdgeType; | 72 GrPrimitiveEdgeType fEdgeType; |
| 72 uint32_t fCircularCornerFlags; | 73 uint32_t fCircularCornerFlags; |
| 73 | 74 |
| 74 GR_DECLARE_EFFECT_TEST; | 75 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| 75 | 76 |
| 76 typedef GrEffect INHERITED; | 77 typedef GrFragmentProcessor INHERITED; |
| 77 }; | 78 }; |
| 78 | 79 |
| 79 GrEffect* CircularRRectEffect::Create(GrEffectEdgeType edgeType, | 80 GrFragmentProcessor* CircularRRectEffect::Create(GrPrimitiveEdgeType edgeType, |
| 80 uint32_t circularCornerFlags, | 81 uint32_t circularCornerFlags, |
| 81 const SkRRect& rrect) { | 82 const SkRRect& rrect) { |
| 82 if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType
!= edgeType) { | 83 if (kFillAA_GrProcessorEdgeType != edgeType && kInverseFillAA_GrProcessorEdg
eType != edgeType) { |
| 83 return NULL; | 84 return NULL; |
| 84 } | 85 } |
| 85 return SkNEW_ARGS(CircularRRectEffect, (edgeType, circularCornerFlags, rrect
)); | 86 return SkNEW_ARGS(CircularRRectEffect, (edgeType, circularCornerFlags, rrect
)); |
| 86 } | 87 } |
| 87 | 88 |
| 88 void CircularRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* v
alidFlags) const { | 89 void CircularRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* v
alidFlags) const { |
| 89 *validFlags = 0; | 90 *validFlags = 0; |
| 90 } | 91 } |
| 91 | 92 |
| 92 const GrBackendEffectFactory& CircularRRectEffect::getFactory() const { | 93 const GrBackendFragmentProcessorFactory& CircularRRectEffect::getFactory() const
{ |
| 93 return GrTBackendEffectFactory<CircularRRectEffect>::getInstance(); | 94 return GrTBackendFragmentProcessorFactory<CircularRRectEffect>::getInstance(
); |
| 94 } | 95 } |
| 95 | 96 |
| 96 CircularRRectEffect::CircularRRectEffect(GrEffectEdgeType edgeType, uint32_t cir
cularCornerFlags, | 97 CircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t
circularCornerFlags, |
| 97 const SkRRect& rrect) | 98 const SkRRect& rrect) |
| 98 : fRRect(rrect) | 99 : fRRect(rrect) |
| 99 , fEdgeType(edgeType) | 100 , fEdgeType(edgeType) |
| 100 , fCircularCornerFlags(circularCornerFlags) { | 101 , fCircularCornerFlags(circularCornerFlags) { |
| 101 this->setWillReadFragmentPosition(); | 102 this->setWillReadFragmentPosition(); |
| 102 } | 103 } |
| 103 | 104 |
| 104 bool CircularRRectEffect::onIsEqual(const GrEffect& other) const { | 105 bool CircularRRectEffect::onIsEqual(const GrProcessor& other) const { |
| 105 const CircularRRectEffect& crre = other.cast<CircularRRectEffect>(); | 106 const CircularRRectEffect& crre = other.cast<CircularRRectEffect>(); |
| 106 // The corner flags are derived from fRRect, so no need to check them. | 107 // The corner flags are derived from fRRect, so no need to check them. |
| 107 return fEdgeType == crre.fEdgeType && fRRect == crre.fRRect; | 108 return fEdgeType == crre.fEdgeType && fRRect == crre.fRRect; |
| 108 } | 109 } |
| 109 | 110 |
| 110 ////////////////////////////////////////////////////////////////////////////// | 111 ////////////////////////////////////////////////////////////////////////////// |
| 111 | 112 |
| 112 GR_DEFINE_EFFECT_TEST(CircularRRectEffect); | 113 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(CircularRRectEffect); |
| 113 | 114 |
| 114 GrEffect* CircularRRectEffect::TestCreate(SkRandom* random, | 115 GrFragmentProcessor* CircularRRectEffect::TestCreate(SkRandom* random, |
| 115 GrContext*, | 116 GrContext*, |
| 116 const GrDrawTargetCaps& caps, | 117 const GrDrawTargetCaps& cap
s, |
| 117 GrTexture*[]) { | 118 GrTexture*[]) { |
| 118 SkScalar w = random->nextRangeScalar(20.f, 1000.f); | 119 SkScalar w = random->nextRangeScalar(20.f, 1000.f); |
| 119 SkScalar h = random->nextRangeScalar(20.f, 1000.f); | 120 SkScalar h = random->nextRangeScalar(20.f, 1000.f); |
| 120 SkScalar r = random->nextRangeF(kRadiusMin, 9.f); | 121 SkScalar r = random->nextRangeF(kRadiusMin, 9.f); |
| 121 SkRRect rrect; | 122 SkRRect rrect; |
| 122 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); | 123 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); |
| 123 GrEffect* effect; | 124 GrFragmentProcessor* fp; |
| 124 do { | 125 do { |
| 125 GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectE
dgeTypeCnt); | 126 GrPrimitiveEdgeType et = |
| 126 effect = GrRRectEffect::Create(et, rrect); | 127 (GrPrimitiveEdgeType)random->nextULessThan(kGrProcessorEdgeTypeC
nt); |
| 127 } while (NULL == effect); | 128 fp = GrRRectEffect::Create(et, rrect); |
| 128 return effect; | 129 } while (NULL == fp); |
| 130 return fp; |
| 129 } | 131 } |
| 130 | 132 |
| 131 ////////////////////////////////////////////////////////////////////////////// | 133 ////////////////////////////////////////////////////////////////////////////// |
| 132 | 134 |
| 133 class GLCircularRRectEffect : public GrGLEffect { | 135 class GLCircularRRectEffect : public GrGLFragmentProcessor { |
| 134 public: | 136 public: |
| 135 GLCircularRRectEffect(const GrBackendEffectFactory&, const GrEffect&); | 137 GLCircularRRectEffect(const GrBackendProcessorFactory&, const GrProcessor&); |
| 136 | 138 |
| 137 virtual void emitCode(GrGLProgramBuilder* builder, | 139 virtual void emitCode(GrGLProgramBuilder* builder, |
| 138 const GrEffect& effect, | 140 const GrFragmentProcessor& fp, |
| 139 const GrEffectKey& key, | 141 const GrProcessorKey& key, |
| 140 const char* outputColor, | 142 const char* outputColor, |
| 141 const char* inputColor, | 143 const char* inputColor, |
| 142 const TransformedCoordsArray&, | 144 const TransformedCoordsArray&, |
| 143 const TextureSamplerArray&) SK_OVERRIDE; | 145 const TextureSamplerArray&) SK_OVERRIDE; |
| 144 | 146 |
| 145 static inline void GenKey(const GrEffect&, const GrGLCaps&, GrEffectKeyBuild
er*); | 147 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKe
yBuilder*); |
| 146 | 148 |
| 147 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVER
RIDE; | 149 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O
VERRIDE; |
| 148 | 150 |
| 149 private: | 151 private: |
| 150 GrGLProgramDataManager::UniformHandle fInnerRectUniform; | 152 GrGLProgramDataManager::UniformHandle fInnerRectUniform; |
| 151 GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform; | 153 GrGLProgramDataManager::UniformHandle fRadiusPlusHalfUniform; |
| 152 SkRRect fPrevRRect; | 154 SkRRect fPrevRRect; |
| 153 typedef GrGLEffect INHERITED; | 155 typedef GrGLFragmentProcessor INHERITED; |
| 154 }; | 156 }; |
| 155 | 157 |
| 156 GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendEffectFactory& facto
ry, | 158 GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendProcessorFactory& fa
ctory, |
| 157 const GrEffect& effect) | 159 const GrProcessor& ) |
| 158 : INHERITED (factory) { | 160 : INHERITED (factory) { |
| 159 fPrevRRect.setEmpty(); | 161 fPrevRRect.setEmpty(); |
| 160 } | 162 } |
| 161 | 163 |
| 162 void GLCircularRRectEffect::emitCode(GrGLProgramBuilder* builder, | 164 void GLCircularRRectEffect::emitCode(GrGLProgramBuilder* builder, |
| 163 const GrEffect& effect, | 165 const GrFragmentProcessor& fp, |
| 164 const GrEffectKey& key, | 166 const GrProcessorKey& key, |
| 165 const char* outputColor, | 167 const char* outputColor, |
| 166 const char* inputColor, | 168 const char* inputColor, |
| 167 const TransformedCoordsArray&, | 169 const TransformedCoordsArray&, |
| 168 const TextureSamplerArray& samplers) { | 170 const TextureSamplerArray& samplers) { |
| 169 const CircularRRectEffect& crre = effect.cast<CircularRRectEffect>(); | 171 const CircularRRectEffect& crre = fp.cast<CircularRRectEffect>(); |
| 170 const char *rectName; | 172 const char *rectName; |
| 171 const char *radiusPlusHalfName; | 173 const char *radiusPlusHalfName; |
| 172 // The inner rect is the rrect bounds inset by the radius. Its left, top, ri
ght, and bottom | 174 // The inner rect is the rrect bounds inset by the radius. Its left, top, ri
ght, and bottom |
| 173 // edges correspond to components x, y, z, and w, respectively. When a side
of the rrect has | 175 // edges correspond to components x, y, z, and w, respectively. When a side
of the rrect has |
| 174 // only rectangular corners, that side's value corresponds to the rect edge'
s value outset by | 176 // only rectangular corners, that side's value corresponds to the rect edge'
s value outset by |
| 175 // half a pixel. | 177 // half a pixel. |
| 176 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 178 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
| 177 kVec4f_GrSLType, | 179 kVec4f_GrSLType, |
| 178 "innerRect", | 180 "innerRect", |
| 179 &rectName); | 181 &rectName); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 fsBuilder->codeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, f
ragmentPos); | 280 fsBuilder->codeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, f
ragmentPos); |
| 279 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP
os, rectName); | 281 fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentP
os, rectName); |
| 280 fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy
1.y), 0.0);\n"); | 282 fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy
1.y), 0.0);\n"); |
| 281 fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0,
1.0);\n", | 283 fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0,
1.0);\n", |
| 282 fragmentPos, rectName); | 284 fragmentPos, rectName); |
| 283 fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng
th(dxy), 0.0, 1.0);\n", | 285 fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - leng
th(dxy), 0.0, 1.0);\n", |
| 284 radiusPlusHalfName); | 286 radiusPlusHalfName); |
| 285 break; | 287 break; |
| 286 } | 288 } |
| 287 | 289 |
| 288 if (kInverseFillAA_GrEffectEdgeType == crre.getEdgeType()) { | 290 if (kInverseFillAA_GrProcessorEdgeType == crre.getEdgeType()) { |
| 289 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); | 291 fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); |
| 290 } | 292 } |
| 291 | 293 |
| 292 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, | 294 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, |
| 293 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); | 295 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); |
| 294 } | 296 } |
| 295 | 297 |
| 296 void GLCircularRRectEffect::GenKey(const GrEffect& effect, const GrGLCaps&, | 298 void GLCircularRRectEffect::GenKey(const GrProcessor& processor, const GrGLCaps&
, |
| 297 GrEffectKeyBuilder* b) { | 299 GrProcessorKeyBuilder* b) { |
| 298 const CircularRRectEffect& crre = effect.cast<CircularRRectEffect>(); | 300 const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>(); |
| 299 GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8); | 301 GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8); |
| 300 b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType()); | 302 b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType()); |
| 301 } | 303 } |
| 302 | 304 |
| 303 void GLCircularRRectEffect::setData(const GrGLProgramDataManager& pdman, | 305 void GLCircularRRectEffect::setData(const GrGLProgramDataManager& pdman, |
| 304 const GrEffect& effect) { | 306 const GrProcessor& processor) { |
| 305 const CircularRRectEffect& crre = effect.cast<CircularRRectEffect>(); | 307 const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>(); |
| 306 const SkRRect& rrect = crre.getRRect(); | 308 const SkRRect& rrect = crre.getRRect(); |
| 307 if (rrect != fPrevRRect) { | 309 if (rrect != fPrevRRect) { |
| 308 SkRect rect = rrect.getBounds(); | 310 SkRect rect = rrect.getBounds(); |
| 309 SkScalar radius = 0; | 311 SkScalar radius = 0; |
| 310 switch (crre.getCircularCornerFlags()) { | 312 switch (crre.getCircularCornerFlags()) { |
| 311 case CircularRRectEffect::kAll_CornerFlags: | 313 case CircularRRectEffect::kAll_CornerFlags: |
| 312 SkASSERT(rrect.isSimpleCircular()); | 314 SkASSERT(rrect.isSimpleCircular()); |
| 313 radius = rrect.getSimpleRadii().fX; | 315 radius = rrect.getSimpleRadii().fX; |
| 314 SkASSERT(radius >= kRadiusMin); | 316 SkASSERT(radius >= kRadiusMin); |
| 315 rect.inset(radius, radius); | 317 rect.inset(radius, radius); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.
fBottom); | 378 pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.
fBottom); |
| 377 pdman.set1f(fRadiusPlusHalfUniform, radius + 0.5f); | 379 pdman.set1f(fRadiusPlusHalfUniform, radius + 0.5f); |
| 378 fPrevRRect = rrect; | 380 fPrevRRect = rrect; |
| 379 } | 381 } |
| 380 } | 382 } |
| 381 | 383 |
| 382 ////////////////////////////////////////////////////////////////////////////// | 384 ////////////////////////////////////////////////////////////////////////////// |
| 383 | 385 |
| 384 class GLEllipticalRRectEffect; | 386 class GLEllipticalRRectEffect; |
| 385 | 387 |
| 386 class EllipticalRRectEffect : public GrEffect { | 388 class EllipticalRRectEffect : public GrFragmentProcessor { |
| 387 public: | 389 public: |
| 388 static GrEffect* Create(GrEffectEdgeType, const SkRRect&); | 390 static GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkRRect&); |
| 389 | 391 |
| 390 virtual ~EllipticalRRectEffect() {}; | 392 virtual ~EllipticalRRectEffect() {}; |
| 391 static const char* Name() { return "EllipticalRRect"; } | 393 static const char* Name() { return "EllipticalRRect"; } |
| 392 | 394 |
| 393 const SkRRect& getRRect() const { return fRRect; } | 395 const SkRRect& getRRect() const { return fRRect; } |
| 394 | 396 |
| 395 | 397 |
| 396 GrEffectEdgeType getEdgeType() const { return fEdgeType; } | 398 GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } |
| 397 | 399 |
| 398 typedef GLEllipticalRRectEffect GLEffect; | 400 typedef GLEllipticalRRectEffect GLProcessor; |
| 399 | 401 |
| 400 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 402 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
| 401 | 403 |
| 402 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 404 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR
IDE; |
| 403 | 405 |
| 404 private: | 406 private: |
| 405 EllipticalRRectEffect(GrEffectEdgeType, const SkRRect&); | 407 EllipticalRRectEffect(GrPrimitiveEdgeType, const SkRRect&); |
| 406 | 408 |
| 407 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; | 409 virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE; |
| 408 | 410 |
| 409 SkRRect fRRect; | 411 SkRRect fRRect; |
| 410 GrEffectEdgeType fEdgeType; | 412 GrPrimitiveEdgeType fEdgeType; |
| 411 | 413 |
| 412 GR_DECLARE_EFFECT_TEST; | 414 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| 413 | 415 |
| 414 typedef GrEffect INHERITED; | 416 typedef GrFragmentProcessor INHERITED; |
| 415 }; | 417 }; |
| 416 | 418 |
| 417 GrEffect* EllipticalRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect
& rrect) { | 419 GrFragmentProcessor* |
| 418 if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType
!= edgeType) { | 420 EllipticalRRectEffect::Create(GrPrimitiveEdgeType edgeType, const SkRRect& rrect
) { |
| 421 if (kFillAA_GrProcessorEdgeType != edgeType && kInverseFillAA_GrProcessorEdg
eType != edgeType) { |
| 419 return NULL; | 422 return NULL; |
| 420 } | 423 } |
| 421 return SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrect)); | 424 return SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrect)); |
| 422 } | 425 } |
| 423 | 426 |
| 424 void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t*
validFlags) const { | 427 void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t*
validFlags) const { |
| 425 *validFlags = 0; | 428 *validFlags = 0; |
| 426 } | 429 } |
| 427 | 430 |
| 428 const GrBackendEffectFactory& EllipticalRRectEffect::getFactory() const { | 431 const GrBackendFragmentProcessorFactory& EllipticalRRectEffect::getFactory() con
st { |
| 429 return GrTBackendEffectFactory<EllipticalRRectEffect>::getInstance(); | 432 return GrTBackendFragmentProcessorFactory<EllipticalRRectEffect>::getInstanc
e(); |
| 430 } | 433 } |
| 431 | 434 |
| 432 EllipticalRRectEffect::EllipticalRRectEffect(GrEffectEdgeType edgeType, const Sk
RRect& rrect) | 435 EllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const
SkRRect& rrect) |
| 433 : fRRect(rrect) | 436 : fRRect(rrect) |
| 434 , fEdgeType(edgeType){ | 437 , fEdgeType(edgeType){ |
| 435 this->setWillReadFragmentPosition(); | 438 this->setWillReadFragmentPosition(); |
| 436 } | 439 } |
| 437 | 440 |
| 438 bool EllipticalRRectEffect::onIsEqual(const GrEffect& other) const { | 441 bool EllipticalRRectEffect::onIsEqual(const GrProcessor& other) const { |
| 439 const EllipticalRRectEffect& erre = other.cast<EllipticalRRectEffect>(); | 442 const EllipticalRRectEffect& erre = other.cast<EllipticalRRectEffect>(); |
| 440 return fEdgeType == erre.fEdgeType && fRRect == erre.fRRect; | 443 return fEdgeType == erre.fEdgeType && fRRect == erre.fRRect; |
| 441 } | 444 } |
| 442 | 445 |
| 443 ////////////////////////////////////////////////////////////////////////////// | 446 ////////////////////////////////////////////////////////////////////////////// |
| 444 | 447 |
| 445 GR_DEFINE_EFFECT_TEST(EllipticalRRectEffect); | 448 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(EllipticalRRectEffect); |
| 446 | 449 |
| 447 GrEffect* EllipticalRRectEffect::TestCreate(SkRandom* random, | 450 GrFragmentProcessor* EllipticalRRectEffect::TestCreate(SkRandom* random, |
| 448 GrContext*, | 451 GrContext*, |
| 449 const GrDrawTargetCaps& caps, | 452 const GrDrawTargetCaps& c
aps, |
| 450 GrTexture*[]) { | 453 GrTexture*[]) { |
| 451 SkScalar w = random->nextRangeScalar(20.f, 1000.f); | 454 SkScalar w = random->nextRangeScalar(20.f, 1000.f); |
| 452 SkScalar h = random->nextRangeScalar(20.f, 1000.f); | 455 SkScalar h = random->nextRangeScalar(20.f, 1000.f); |
| 453 SkVector r[4]; | 456 SkVector r[4]; |
| 454 r[SkRRect::kUpperLeft_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); | 457 r[SkRRect::kUpperLeft_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); |
| 455 // ensure at least one corner really is elliptical | 458 // ensure at least one corner really is elliptical |
| 456 do { | 459 do { |
| 457 r[SkRRect::kUpperLeft_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); | 460 r[SkRRect::kUpperLeft_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); |
| 458 } while (r[SkRRect::kUpperLeft_Corner].fY == r[SkRRect::kUpperLeft_Corner].f
X); | 461 } while (r[SkRRect::kUpperLeft_Corner].fY == r[SkRRect::kUpperLeft_Corner].f
X); |
| 459 | 462 |
| 460 SkRRect rrect; | 463 SkRRect rrect; |
| 461 if (random->nextBool()) { | 464 if (random->nextBool()) { |
| 462 // half the time create a four-radii rrect. | 465 // half the time create a four-radii rrect. |
| 463 r[SkRRect::kLowerRight_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); | 466 r[SkRRect::kLowerRight_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); |
| 464 r[SkRRect::kLowerRight_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); | 467 r[SkRRect::kLowerRight_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); |
| 465 | 468 |
| 466 r[SkRRect::kUpperRight_Corner].fX = r[SkRRect::kLowerRight_Corner].fX; | 469 r[SkRRect::kUpperRight_Corner].fX = r[SkRRect::kLowerRight_Corner].fX; |
| 467 r[SkRRect::kUpperRight_Corner].fY = r[SkRRect::kUpperLeft_Corner].fY; | 470 r[SkRRect::kUpperRight_Corner].fY = r[SkRRect::kUpperLeft_Corner].fY; |
| 468 | 471 |
| 469 r[SkRRect::kLowerLeft_Corner].fX = r[SkRRect::kUpperLeft_Corner].fX; | 472 r[SkRRect::kLowerLeft_Corner].fX = r[SkRRect::kUpperLeft_Corner].fX; |
| 470 r[SkRRect::kLowerLeft_Corner].fY = r[SkRRect::kLowerRight_Corner].fY; | 473 r[SkRRect::kLowerLeft_Corner].fY = r[SkRRect::kLowerRight_Corner].fY; |
| 471 | 474 |
| 472 rrect.setRectRadii(SkRect::MakeWH(w, h), r); | 475 rrect.setRectRadii(SkRect::MakeWH(w, h), r); |
| 473 } else { | 476 } else { |
| 474 rrect.setRectXY(SkRect::MakeWH(w, h), r[SkRRect::kUpperLeft_Corner].fX, | 477 rrect.setRectXY(SkRect::MakeWH(w, h), r[SkRRect::kUpperLeft_Corner].fX, |
| 475 r[SkRRect::kUpperLeft_Corner].fY); | 478 r[SkRRect::kUpperLeft_Corner].fY); |
| 476 } | 479 } |
| 477 GrEffect* effect; | 480 GrFragmentProcessor* fp; |
| 478 do { | 481 do { |
| 479 GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectE
dgeTypeCnt); | 482 GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)random->nextULessThan(kGrP
rocessorEdgeTypeCnt); |
| 480 effect = GrRRectEffect::Create(et, rrect); | 483 fp = GrRRectEffect::Create(et, rrect); |
| 481 } while (NULL == effect); | 484 } while (NULL == fp); |
| 482 return effect; | 485 return fp; |
| 483 } | 486 } |
| 484 | 487 |
| 485 ////////////////////////////////////////////////////////////////////////////// | 488 ////////////////////////////////////////////////////////////////////////////// |
| 486 | 489 |
| 487 class GLEllipticalRRectEffect : public GrGLEffect { | 490 class GLEllipticalRRectEffect : public GrGLFragmentProcessor { |
| 488 public: | 491 public: |
| 489 GLEllipticalRRectEffect(const GrBackendEffectFactory&, const GrEffect&); | 492 GLEllipticalRRectEffect(const GrBackendProcessorFactory&, const GrProcessor&
); |
| 490 | 493 |
| 491 virtual void emitCode(GrGLProgramBuilder* builder, | 494 virtual void emitCode(GrGLProgramBuilder* builder, |
| 492 const GrEffect& effect, | 495 const GrFragmentProcessor& effect, |
| 493 const GrEffectKey& key, | 496 const GrProcessorKey& key, |
| 494 const char* outputColor, | 497 const char* outputColor, |
| 495 const char* inputColor, | 498 const char* inputColor, |
| 496 const TransformedCoordsArray&, | 499 const TransformedCoordsArray&, |
| 497 const TextureSamplerArray&) SK_OVERRIDE; | 500 const TextureSamplerArray&) SK_OVERRIDE; |
| 498 | 501 |
| 499 static inline void GenKey(const GrEffect&, const GrGLCaps&, GrEffectKeyBuild
er*); | 502 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKe
yBuilder*); |
| 500 | 503 |
| 501 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVER
RIDE; | 504 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O
VERRIDE; |
| 502 | 505 |
| 503 private: | 506 private: |
| 504 GrGLProgramDataManager::UniformHandle fInnerRectUniform; | 507 GrGLProgramDataManager::UniformHandle fInnerRectUniform; |
| 505 GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform; | 508 GrGLProgramDataManager::UniformHandle fInvRadiiSqdUniform; |
| 506 SkRRect fPrevRRect; | 509 SkRRect fPrevRRect; |
| 507 typedef GrGLEffect INHERITED; | 510 typedef GrGLFragmentProcessor INHERITED; |
| 508 }; | 511 }; |
| 509 | 512 |
| 510 GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendEffectFactory& f
actory, | 513 GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendProcessorFactory
& factory, |
| 511 const GrEffect& effect) | 514 const GrProcessor& effect) |
| 512 : INHERITED (factory) { | 515 : INHERITED (factory) { |
| 513 fPrevRRect.setEmpty(); | 516 fPrevRRect.setEmpty(); |
| 514 } | 517 } |
| 515 | 518 |
| 516 void GLEllipticalRRectEffect::emitCode(GrGLProgramBuilder* builder, | 519 void GLEllipticalRRectEffect::emitCode(GrGLProgramBuilder* builder, |
| 517 const GrEffect& effect, | 520 const GrFragmentProcessor& effect, |
| 518 const GrEffectKey& key, | 521 const GrProcessorKey& key, |
| 519 const char* outputColor, | 522 const char* outputColor, |
| 520 const char* inputColor, | 523 const char* inputColor, |
| 521 const TransformedCoordsArray&, | 524 const TransformedCoordsArray&, |
| 522 const TextureSamplerArray& samplers) { | 525 const TextureSamplerArray& samplers) { |
| 523 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); | 526 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); |
| 524 const char *rectName; | 527 const char *rectName; |
| 525 // The inner rect is the rrect bounds inset by the x/y radii | 528 // The inner rect is the rrect bounds inset by the x/y radii |
| 526 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | 529 fInnerRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
| 527 kVec4f_GrSLType, | 530 kVec4f_GrSLType, |
| 528 "innerRect", | 531 "innerRect", |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 SkFAIL("RRect should always be simple or nine-patch."); | 576 SkFAIL("RRect should always be simple or nine-patch."); |
| 574 } | 577 } |
| 575 // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1. | 578 // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1. |
| 576 fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n"); | 579 fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n"); |
| 577 // grad_dot is the squared length of the gradient of the implicit. | 580 // grad_dot is the squared length of the gradient of the implicit. |
| 578 fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n"); | 581 fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n"); |
| 579 // avoid calling inversesqrt on zero. | 582 // avoid calling inversesqrt on zero. |
| 580 fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n"); | 583 fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n"); |
| 581 fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_
dot);\n"); | 584 fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_
dot);\n"); |
| 582 | 585 |
| 583 if (kFillAA_GrEffectEdgeType == erre.getEdgeType()) { | 586 if (kFillAA_GrProcessorEdgeType == erre.getEdgeType()) { |
| 584 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1
.0);\n"); | 587 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1
.0);\n"); |
| 585 } else { | 588 } else { |
| 586 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1
.0);\n"); | 589 fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1
.0);\n"); |
| 587 } | 590 } |
| 588 | 591 |
| 589 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, | 592 fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, |
| 590 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); | 593 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st
r()); |
| 591 } | 594 } |
| 592 | 595 |
| 593 void GLEllipticalRRectEffect::GenKey(const GrEffect& effect, const GrGLCaps&, | 596 void GLEllipticalRRectEffect::GenKey(const GrProcessor& effect, const GrGLCaps&, |
| 594 GrEffectKeyBuilder* b) { | 597 GrProcessorKeyBuilder* b) { |
| 595 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); | 598 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); |
| 596 GR_STATIC_ASSERT(kLast_GrEffectEdgeType < (1 << 3)); | 599 GR_STATIC_ASSERT(kLast_GrProcessorEdgeType < (1 << 3)); |
| 597 b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3); | 600 b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3); |
| 598 } | 601 } |
| 599 | 602 |
| 600 void GLEllipticalRRectEffect::setData(const GrGLProgramDataManager& pdman, | 603 void GLEllipticalRRectEffect::setData(const GrGLProgramDataManager& pdman, |
| 601 const GrEffect& effect) { | 604 const GrProcessor& effect) { |
| 602 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); | 605 const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>(); |
| 603 const SkRRect& rrect = erre.getRRect(); | 606 const SkRRect& rrect = erre.getRRect(); |
| 604 if (rrect != fPrevRRect) { | 607 if (rrect != fPrevRRect) { |
| 605 SkRect rect = rrect.getBounds(); | 608 SkRect rect = rrect.getBounds(); |
| 606 const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner); | 609 const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner); |
| 607 SkASSERT(r0.fX >= kRadiusMin); | 610 SkASSERT(r0.fX >= kRadiusMin); |
| 608 SkASSERT(r0.fY >= kRadiusMin); | 611 SkASSERT(r0.fY >= kRadiusMin); |
| 609 switch (erre.getRRect().getType()) { | 612 switch (erre.getRRect().getType()) { |
| 610 case SkRRect::kSimple_Type: | 613 case SkRRect::kSimple_Type: |
| 611 rect.inset(r0.fX, r0.fY); | 614 rect.inset(r0.fX, r0.fY); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 629 default: | 632 default: |
| 630 SkFAIL("RRect should always be simple or nine-patch."); | 633 SkFAIL("RRect should always be simple or nine-patch."); |
| 631 } | 634 } |
| 632 pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.
fBottom); | 635 pdman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.
fBottom); |
| 633 fPrevRRect = rrect; | 636 fPrevRRect = rrect; |
| 634 } | 637 } |
| 635 } | 638 } |
| 636 | 639 |
| 637 ////////////////////////////////////////////////////////////////////////////// | 640 ////////////////////////////////////////////////////////////////////////////// |
| 638 | 641 |
| 639 GrEffect* GrRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect& rrect)
{ | 642 GrFragmentProcessor* GrRRectEffect::Create(GrPrimitiveEdgeType edgeType, const S
kRRect& rrect) { |
| 640 if (rrect.isRect()) { | 643 if (rrect.isRect()) { |
| 641 return GrConvexPolyEffect::Create(edgeType, rrect.getBounds()); | 644 return GrConvexPolyEffect::Create(edgeType, rrect.getBounds()); |
| 642 } | 645 } |
| 643 | 646 |
| 644 if (rrect.isOval()) { | 647 if (rrect.isOval()) { |
| 645 return GrOvalEffect::Create(edgeType, rrect.getBounds()); | 648 return GrOvalEffect::Create(edgeType, rrect.getBounds()); |
| 646 } | 649 } |
| 647 | 650 |
| 648 if (rrect.isSimple()) { | 651 if (rrect.isSimple()) { |
| 649 if (rrect.getSimpleRadii().fX < kRadiusMin || rrect.getSimpleRadii().fY
< kRadiusMin) { | 652 if (rrect.getSimpleRadii().fX < kRadiusMin || rrect.getSimpleRadii().fY
< kRadiusMin) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 if (rrect.isNinePatch()) { | 728 if (rrect.isNinePatch()) { |
| 726 return EllipticalRRectEffect::Create(edgeType, rrect); | 729 return EllipticalRRectEffect::Create(edgeType, rrect); |
| 727 } | 730 } |
| 728 return NULL; | 731 return NULL; |
| 729 } | 732 } |
| 730 } | 733 } |
| 731 } | 734 } |
| 732 | 735 |
| 733 return NULL; | 736 return NULL; |
| 734 } | 737 } |
| OLD | NEW |