Index: src/gpu/effects/GrRectEffect.cpp |
=================================================================== |
--- src/gpu/effects/GrRectEffect.cpp (revision 0) |
+++ src/gpu/effects/GrRectEffect.cpp (revision 0) |
@@ -0,0 +1,102 @@ |
+/* |
+ * Copyright 2013 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "GrRectEffect.h" |
+#include "gl/GrGLEffect.h" |
+#include "gl/GrGLEffectMatrix.h" |
+#include "gl/GrGLSL.h" |
+#include "gl/GrGLTexture.h" |
+#include "GrTBackendEffectFactory.h" |
+#include "GrTexture.h" |
+ |
+class GrGLRectEffect : public GrGLEffect { |
+public: |
+ GrGLRectEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) |
+ : INHERITED (factory) {} |
+ |
+ virtual void emitCode(GrGLShaderBuilder* builder, |
+ const GrDrawEffect& drawEffect, |
+ EffectKey key, |
+ const char* outputColor, |
+ const char* inputColor, |
+ const TextureSamplerArray& samplers) SK_OVERRIDE { |
+ // setup the varying for the center point and the unit vector |
+ // that points down the height of the rect |
+ const char *vsRectEdgeName, *fsRectEdgeName; |
+ builder->addVarying(kVec4f_GrSLType, "RectEdge", |
+ &vsRectEdgeName, &fsRectEdgeName); |
+ const SkString* attr0Name = |
+ builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); |
+ builder->vsCodeAppendf("\t%s = %s;\n", vsRectEdgeName, attr0Name->c_str()); |
+ |
+ // setup the varying for width/2+.5 and height/2+.5 |
+ const char *vsWidthHeightName, *fsWidthHeightName; |
+ builder->addVarying(kVec2f_GrSLType, "WidthHeight", |
+ &vsWidthHeightName, &fsWidthHeightName); |
+ const SkString* attr1Name = |
+ builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]); |
+ builder->vsCodeAppendf("\t%s = %s;\n", vsWidthHeightName, attr1Name->c_str()); |
+ |
+ // These scale factors adjust the coverage for < 1 pixel wide/high rects |
+ builder->fsCodeAppendf("\tfloat wScale = max(1.0, 2.0/(0.5+%s.x));\n", fsWidthHeightName); |
bsalomon
2013/04/08 15:48:39
Do you think it makes sense to do this in the VS?
robertphillips
2013/04/08 19:33:20
Yes but I would like to delay to the next revision
|
+ builder->fsCodeAppendf("\tfloat hScale = max(1.0, 2.0/(0.5+%s.y));\n", fsWidthHeightName); |
+ |
+ // Compute the coverage for the rect's width |
+ builder->fsCodeAppendf("\tvec2 offset = %s.xy - %s.xy;\n", |
+ builder->fragmentPosition(), fsRectEdgeName); |
+ builder->fsCodeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n", |
+ fsRectEdgeName, fsRectEdgeName); |
+ builder->fsCodeAppendf("\tfloat coverage = clamp(wScale*(%s.x-perpDot), 0.0, 1.0);\n", |
+ fsWidthHeightName); |
+ |
+ // Compute the coverage for the rect's height and merge with the width |
+ builder->fsCodeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n", |
+ fsRectEdgeName); |
+ builder->fsCodeAppendf("\tcoverage = min(coverage, clamp(hScale*(%s.y-perpDot), 0.0, 1.0));\n", |
+ fsWidthHeightName); |
+ |
+ SkString modulate; |
+ GrGLSLModulate4f(&modulate, inputColor, "coverage"); |
+ builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); |
+ } |
+ |
+ static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { |
+ return 0; |
+ } |
+ |
+ virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE { |
+ } |
+ |
+private: |
+ typedef GrGLEffect INHERITED; |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+GrRectEffect::GrRectEffect() : GrEffect() { |
+ this->addVertexAttrib(kVec4f_GrSLType); |
+ this->addVertexAttrib(kVec2f_GrSLType); |
+} |
+ |
+void GrRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { |
+ *validFlags = 0; |
+} |
+ |
+const GrBackendEffectFactory& GrRectEffect::getFactory() const { |
+ return GrTBackendEffectFactory<GrRectEffect>::getInstance(); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+GR_DEFINE_EFFECT_TEST(GrRectEffect); |
+ |
+GrEffectRef* GrRectEffect::TestCreate(SkMWCRandom* random, |
+ GrContext* context, |
+ const GrDrawTargetCaps&, |
+ GrTexture* textures[]) { |
+ return GrRectEffect::Create(); |
+} |