Chromium Code Reviews| 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 "GrConvexPolyEffect.h" | 8 #include "GrConvexPolyEffect.h" |
| 9 | 9 |
| 10 #include "gl/GrGLEffect.h" | 10 #include "gl/GrGLEffect.h" |
| 11 #include "gl/GrGLSL.h" | 11 #include "gl/GrGLSL.h" |
| 12 #include "gl/GrGLVertexEffect.h" | 12 #include "gl/GrGLVertexEffect.h" |
| 13 #include "GrTBackendEffectFactory.h" | 13 #include "GrTBackendEffectFactory.h" |
| 14 | 14 |
| 15 #include "SkPath.h" | 15 #include "SkPath.h" |
| 16 | 16 |
| 17 ////////////////////////////////////////////////////////////////////////////// | |
| 18 class GLAARectEffect; | |
| 19 | |
| 20 class AARectEffect : public GrEffect { | |
| 21 public: | |
| 22 typedef GLAARectEffect GLEffect; | |
| 23 | |
| 24 const SkRect& getRect() const { return fRect; } | |
| 25 | |
| 26 static const char* Name() { return "AARect"; } | |
| 27 | |
| 28 static GrEffectRef* Create(const SkRect& rect) { | |
| 29 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(AARectEffect, (rect))) ); | |
| 30 } | |
| 31 | |
| 32 virtual void getConstantColorComponents(GrColor* color, | |
| 33 uint32_t* validFlags) const SK_OVERR IDE { | |
| 34 if (fRect.isEmpty()) { | |
| 35 // An empty rect will have no coverage anywhere. | |
| 36 *color = 0x00000000; | |
| 37 *validFlags = kRGBA_GrColorComponentFlags; | |
| 38 } else { | |
| 39 *validFlags = 0; | |
| 40 } | |
| 41 } | |
| 42 | |
| 43 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | |
| 44 | |
| 45 private: | |
| 46 AARectEffect(const SkRect& rect) : fRect(rect) { | |
| 47 this->setWillReadFragmentPosition(); | |
| 48 } | |
| 49 | |
| 50 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | |
| 51 const AARectEffect& aare = CastEffect<AARectEffect>(other); | |
| 52 return fRect == aare.fRect; | |
| 53 } | |
| 54 | |
| 55 SkRect fRect; | |
| 56 typedef GrEffect INHERITED; | |
| 57 | |
| 58 GR_DECLARE_EFFECT_TEST; | |
| 59 | |
| 60 }; | |
| 61 | |
| 62 GR_DEFINE_EFFECT_TEST(AARectEffect); | |
| 63 | |
| 64 GrEffectRef* AARectEffect::TestCreate(SkRandom* random, | |
| 65 GrContext*, | |
| 66 const GrDrawTargetCaps& caps, | |
| 67 GrTexture*[]) { | |
| 68 SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(), | |
| 69 random->nextSScalar1(), | |
| 70 random->nextSScalar1(), | |
| 71 random->nextSScalar1()); | |
| 72 return AARectEffect::Create(rect); | |
| 73 } | |
| 74 | |
| 75 ////////////////////////////////////////////////////////////////////////////// | |
| 76 | |
| 77 class GLAARectEffect : public GrGLEffect { | |
| 78 public: | |
| 79 GLAARectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | |
| 80 | |
| 81 virtual void emitCode(GrGLShaderBuilder* builder, | |
| 82 const GrDrawEffect& drawEffect, | |
| 83 EffectKey key, | |
| 84 const char* outputColor, | |
| 85 const char* inputColor, | |
| 86 const TransformedCoordsArray&, | |
| 87 const TextureSamplerArray&) SK_OVERRIDE; | |
| 88 | |
| 89 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { retur n 0; } | |
| 90 | |
| 91 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE; | |
| 92 | |
| 93 private: | |
| 94 GrGLUniformManager::UniformHandle fRectUniform; | |
| 95 SkRect fPrevRect; | |
| 96 typedef GrGLEffect INHERITED; | |
| 97 }; | |
| 98 | |
| 99 GLAARectEffect::GLAARectEffect(const GrBackendEffectFactory& factory, | |
| 100 const GrDrawEffect& drawEffect) | |
|
robertphillips
2014/02/04 19:38:50
tab here?
bsalomon
2014/02/08 19:18:01
Done.
| |
| 101 : INHERITED (factory) { | |
| 102 fPrevRect.fLeft = SK_ScalarNaN; | |
| 103 } | |
| 104 | |
| 105 void GLAARectEffect::emitCode(GrGLShaderBuilder* builder, | |
| 106 const GrDrawEffect& drawEffect, | |
| 107 EffectKey key, | |
| 108 const char* outputColor, | |
| 109 const char* inputColor, | |
| 110 const TransformedCoordsArray&, | |
| 111 const TextureSamplerArray& samplers) { | |
| 112 const char *rectName; | |
| 113 fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | |
| 114 kVec4f_GrSLType, | |
| 115 "rect", | |
| 116 &rectName); | |
| 117 const char* fragmentPos = builder->fragmentPosition(); | |
| 118 // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bot tom - 0.5), | |
| 119 // respectively. | |
|
robertphillips
2014/02/04 19:38:50
Maybe a more expansive comment about how coverage
bsalomon
2014/02/08 19:18:01
Done.
| |
| 120 builder->fsCodeAppend("\t\tfloat xSub, ySub;\n"); | |
| 121 builder->fsCodeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, r ectName); | |
| 122 builder->fsCodeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fra gmentPos); | |
| 123 builder->fsCodeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, r ectName); | |
| 124 builder->fsCodeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fra gmentPos); | |
| 125 builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + m ax(ySub, -1.0));\n"); | |
| 126 | |
| 127 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, | |
| 128 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); | |
| 129 } | |
| 130 | |
| 131 void GLAARectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) { | |
| 132 const AARectEffect& aare = drawEffect.castEffect<AARectEffect>(); | |
| 133 const SkRect& rect = aare.getRect(); | |
|
robertphillips
2014/02/04 19:38:50
Do you think this caching will actually pay off?
bsalomon
2014/02/08 19:18:01
We can have the same clip active for a lot of draw
| |
| 134 if (rect != fPrevRect) { | |
| 135 uman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, | |
| 136 rect.fRight - 0.5f, rect.fBottom - 0.5f); | |
| 137 fPrevRect = rect; | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 const GrBackendEffectFactory& AARectEffect::getFactory() const { | |
| 142 return GrTBackendEffectFactory<AARectEffect>::getInstance(); | |
| 143 } | |
| 144 | |
| 145 ////////////////////////////////////////////////////////////////////////////// | |
| 146 | |
| 17 class GrGLConvexPolyEffect : public GrGLEffect { | 147 class GrGLConvexPolyEffect : public GrGLEffect { |
| 18 public: | 148 public: |
| 19 GrGLConvexPolyEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 149 GrGLConvexPolyEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
| 20 | 150 |
| 21 virtual void emitCode(GrGLShaderBuilder* builder, | 151 virtual void emitCode(GrGLShaderBuilder* builder, |
| 22 const GrDrawEffect& drawEffect, | 152 const GrDrawEffect& drawEffect, |
| 23 EffectKey key, | 153 EffectKey key, |
| 24 const char* outputColor, | 154 const char* outputColor, |
| 25 const char* inputColor, | 155 const char* inputColor, |
| 26 const TransformedCoordsArray&, | 156 const TransformedCoordsArray&, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); | 198 builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); |
| 69 builder->fsCodeAppend("\t\talpha *= edge;\n"); | 199 builder->fsCodeAppend("\t\talpha *= edge;\n"); |
| 70 break; | 200 break; |
| 71 case GrConvexPolyEffect::kFillNoAA_EdgeType: | 201 case GrConvexPolyEffect::kFillNoAA_EdgeType: |
| 72 builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); | 202 builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); |
| 73 builder->fsCodeAppend("\t\talpha *= edge;\n"); | 203 builder->fsCodeAppend("\t\talpha *= edge;\n"); |
| 74 break; | 204 break; |
| 75 } | 205 } |
| 76 } | 206 } |
| 77 | 207 |
| 78 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, | 208 builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, |
| 79 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); | 209 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_st r()); |
| 80 } | 210 } |
| 81 | 211 |
| 82 void GrGLConvexPolyEffect::setData(const GrGLUniformManager& uman, const GrDrawE ffect& drawEffect) { | 212 void GrGLConvexPolyEffect::setData(const GrGLUniformManager& uman, const GrDrawE ffect& drawEffect) { |
| 83 const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>(); | 213 const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>(); |
| 84 size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar); | 214 size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar); |
| 85 if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) { | 215 if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) { |
| 86 uman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges()); | 216 uman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges()); |
| 87 memcpy(fPrevEdges, cpe.getEdges(), byteSize); | 217 memcpy(fPrevEdges, cpe.getEdges(), byteSize); |
| 88 } | 218 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 edges[3 * n] = -v.fY; | 257 edges[3 * n] = -v.fY; |
| 128 edges[3 * n + 1] = v.fX; | 258 edges[3 * n + 1] = v.fX; |
| 129 } | 259 } |
| 130 edges[3 * n + 2] = -(edges[3 * n] * pts[i].fX + edges[3 * n + 1] * p ts[i].fY); | 260 edges[3 * n + 2] = -(edges[3 * n] * pts[i].fX + edges[3 * n + 1] * p ts[i].fY); |
| 131 ++n; | 261 ++n; |
| 132 } | 262 } |
| 133 } | 263 } |
| 134 return Create(type, n, edges); | 264 return Create(type, n, edges); |
| 135 } | 265 } |
| 136 | 266 |
| 267 GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkRect& rect) { | |
| 268 if (type == kFillAA_EdgeType) { | |
| 269 return AARectEffect::Create(rect); | |
| 270 } else { | |
|
robertphillips
2014/02/04 19:38:50
It seems like we would never want to take this pat
bsalomon
2014/02/08 19:18:01
True. I changed the function to CreateAAFillRect a
| |
| 271 SkPath path; | |
| 272 path.addRect(rect); | |
| 273 return Create(type, path); | |
| 274 } | |
| 275 } | |
| 276 | |
| 137 GrConvexPolyEffect::~GrConvexPolyEffect() {} | 277 GrConvexPolyEffect::~GrConvexPolyEffect() {} |
| 138 | 278 |
| 139 void GrConvexPolyEffect::getConstantColorComponents(GrColor* color, uint32_t* va lidFlags) const { | 279 void GrConvexPolyEffect::getConstantColorComponents(GrColor* color, uint32_t* va lidFlags) const { |
| 140 *validFlags = 0; | 280 *validFlags = 0; |
| 141 } | 281 } |
| 142 | 282 |
| 143 const GrBackendEffectFactory& GrConvexPolyEffect::getFactory() const { | 283 const GrBackendEffectFactory& GrConvexPolyEffect::getFactory() const { |
| 144 return GrTBackendEffectFactory<GrConvexPolyEffect>::getInstance(); | 284 return GrTBackendEffectFactory<GrConvexPolyEffect>::getInstance(); |
| 145 } | 285 } |
| 146 | 286 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 175 GrTexture*[]) { | 315 GrTexture*[]) { |
| 176 EdgeType edgeType = static_cast<EdgeType>(random->nextULessThan(kEdgeTypeCnt )); | 316 EdgeType edgeType = static_cast<EdgeType>(random->nextULessThan(kEdgeTypeCnt )); |
| 177 int count = random->nextULessThan(kMaxEdges) + 1; | 317 int count = random->nextULessThan(kMaxEdges) + 1; |
| 178 SkScalar edges[kMaxEdges * 3]; | 318 SkScalar edges[kMaxEdges * 3]; |
| 179 for (int i = 0; i < 3 * count; ++i) { | 319 for (int i = 0; i < 3 * count; ++i) { |
| 180 edges[i] = random->nextSScalar1(); | 320 edges[i] = random->nextSScalar1(); |
| 181 } | 321 } |
| 182 | 322 |
| 183 return GrConvexPolyEffect::Create(edgeType, count, edges); | 323 return GrConvexPolyEffect::Create(edgeType, count, edges); |
| 184 } | 324 } |
| OLD | NEW |