blob: 12f3197d55273a8f629c4b5fc6466fe202955dba [file] [log] [blame]
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrEllipseEdgeEffect.h"
9#include "gl/GrGLEffect.h"
10#include "gl/GrGLEffectMatrix.h"
11#include "gl/GrGLSL.h"
12#include "gl/GrGLTexture.h"
13#include "GrTBackendEffectFactory.h"
14#include "GrTexture.h"
15
16class GrGLEllipseEdgeEffect : public GrGLEffect {
17public:
bsalomon@google.comae81d5c2013-03-20 17:32:27 +000018 GrGLEllipseEdgeEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000019 : INHERITED (factory) {}
20
21 virtual void emitCode(GrGLShaderBuilder* builder,
bsalomon@google.comae81d5c2013-03-20 17:32:27 +000022 const GrDrawEffect& drawEffect,
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000023 EffectKey key,
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000024 const char* outputColor,
25 const char* inputColor,
26 const TextureSamplerArray& samplers) SK_OVERRIDE {
bsalomon@google.comae81d5c2013-03-20 17:32:27 +000027 const GrEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<GrEllipseEdgeEffect>();
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +000028
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000029 const char *vsCenterName, *fsCenterName;
30 const char *vsEdgeName, *fsEdgeName;
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000031
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000032 builder->addVarying(kVec2f_GrSLType, "EllipseCenter", &vsCenterName, &fsCenterName);
33 const SkString* attr0Name =
bsalomon@google.comae81d5c2013-03-20 17:32:27 +000034 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000035 builder->vsCodeAppendf("\t%s = %s;\n", vsCenterName, attr0Name->c_str());
skia.committer@gmail.com91274b92013-03-13 07:01:04 +000036
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000037 builder->addVarying(kVec4f_GrSLType, "EllipseEdge", &vsEdgeName, &fsEdgeName);
38 const SkString* attr1Name =
bsalomon@google.comae81d5c2013-03-20 17:32:27 +000039 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000040 builder->vsCodeAppendf("\t%s = %s;\n", vsEdgeName, attr1Name->c_str());
41
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000042 // translate to origin
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000043 builder->fsCodeAppendf("\tvec2 outerOffset = (%s.xy - %s.xy);\n",
44 builder->fragmentPosition(), fsCenterName);
45 builder->fsCodeAppend("\tvec2 innerOffset = outerOffset;\n");
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000046 // scale y by xRadius/yRadius
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000047 builder->fsCodeAppendf("\touterOffset.y *= %s.y;\n", fsEdgeName);
48 builder->fsCodeAppend("\tfloat dOuter = length(outerOffset);\n");
49 // compare outer lengths against xOuterRadius
50 builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.x-dOuter, 0.0, 1.0);\n", fsEdgeName);
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +000051
bsalomon@google.comae81d5c2013-03-20 17:32:27 +000052 if (ellipseEffect.isStroked()) {
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000053 builder->fsCodeAppendf("\tinnerOffset.y *= %s.w;\n", fsEdgeName);
54 builder->fsCodeAppend("\tfloat dInner = length(innerOffset);\n");
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +000055
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000056 // compare inner lengths against xInnerRadius
57 builder->fsCodeAppendf("\tfloat innerAlpha = clamp(dInner-%s.z, 0.0, 1.0);\n", fsEdgeName);
58 builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n");
59 }
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +000060
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000061 SkString modulate;
62 GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha");
63 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
64 }
65
bsalomon@google.comae81d5c2013-03-20 17:32:27 +000066 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
67 const GrEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<GrEllipseEdgeEffect>();
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000068
bsalomon@google.comae81d5c2013-03-20 17:32:27 +000069 return ellipseEffect.isStroked() ? 0x1 : 0x0;
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000070 }
71
bsalomon@google.comae81d5c2013-03-20 17:32:27 +000072 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000073 }
74
75private:
76 typedef GrGLEffect INHERITED;
77};
78
79///////////////////////////////////////////////////////////////////////////////
80
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000081GrEllipseEdgeEffect::GrEllipseEdgeEffect(bool stroke) : GrEffect() {
82 this->addVertexAttrib(kVec2f_GrSLType);
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000083 this->addVertexAttrib(kVec4f_GrSLType);
skia.committer@gmail.com01c34ee2013-03-20 07:01:02 +000084
jvanverth@google.com65eb4d52013-03-19 18:51:02 +000085 fStroke = stroke;
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000086}
87
88void GrEllipseEdgeEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
89 *validFlags = 0;
90}
91
92const GrBackendEffectFactory& GrEllipseEdgeEffect::getFactory() const {
93 return GrTBackendEffectFactory<GrEllipseEdgeEffect>::getInstance();
94}
95
96///////////////////////////////////////////////////////////////////////////////
97
98GR_DEFINE_EFFECT_TEST(GrEllipseEdgeEffect);
99
100GrEffectRef* GrEllipseEdgeEffect::TestCreate(SkMWCRandom* random,
101 GrContext* context,
102 GrTexture* textures[]) {
jvanverth@google.com65eb4d52013-03-19 18:51:02 +0000103 return GrEllipseEdgeEffect::Create(random->nextBool());
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000104}