Revert of Default geometry processor (patchset #9 id:160001 of https://codereview.chromium.org/678953002/)
Reason for revert: breaks nexus 5 Original issue's description: > Default geometry processor > > BUG=skia: > > Committed: https://skia.googlesource.com/skia/+/ff343074b2a3fdaa5f120600e28717e366bceadd TBR=bsalomon@google.com,joshualitt@chromium.org NOTREECHECKS=true NOTRY=true BUG=skia: Review URL: https://codereview.chromium.org/691313003
This commit is contained in:
parent
ff343074b2
commit
ee0ea3f0dd
@ -72,8 +72,6 @@
|
|||||||
'<(skia_src_path)/gpu/GrClipMaskManager.h',
|
'<(skia_src_path)/gpu/GrClipMaskManager.h',
|
||||||
'<(skia_src_path)/gpu/GrClipMaskManager.cpp',
|
'<(skia_src_path)/gpu/GrClipMaskManager.cpp',
|
||||||
'<(skia_src_path)/gpu/GrContext.cpp',
|
'<(skia_src_path)/gpu/GrContext.cpp',
|
||||||
'<(skia_src_path)/gpu/GrDefaultGeoProcFactory.cpp',
|
|
||||||
'<(skia_src_path)/gpu/GrDefaultGeoProcFactory.h',
|
|
||||||
'<(skia_src_path)/gpu/GrDefaultPathRenderer.cpp',
|
'<(skia_src_path)/gpu/GrDefaultPathRenderer.cpp',
|
||||||
'<(skia_src_path)/gpu/GrDefaultPathRenderer.h',
|
'<(skia_src_path)/gpu/GrDefaultPathRenderer.h',
|
||||||
'<(skia_src_path)/gpu/GrDistanceFieldTextContext.h',
|
'<(skia_src_path)/gpu/GrDistanceFieldTextContext.h',
|
||||||
|
@ -43,7 +43,7 @@ public:
|
|||||||
/** Returns true if this and other processor conservatively draw identically. It can only return
|
/** Returns true if this and other processor conservatively draw identically. It can only return
|
||||||
true when the two prcoessors are of the same subclass (i.e. they return the same object from
|
true when the two prcoessors are of the same subclass (i.e. they return the same object from
|
||||||
from getFactory()).
|
from getFactory()).
|
||||||
A return value of true from isEqual() should not be used to test whether the processors
|
A return value of true from isEqual() should not be used to test whether the prcoessors
|
||||||
would generate the same shader code. To test for identical code generation use the
|
would generate the same shader code. To test for identical code generation use the
|
||||||
processors' keys computed by the GrBackendEffectFactory. */
|
processors' keys computed by the GrBackendEffectFactory. */
|
||||||
bool isEqual(const GrGeometryProcessor& that) const {
|
bool isEqual(const GrGeometryProcessor& that) const {
|
||||||
|
@ -561,10 +561,6 @@ public:
|
|||||||
const GrShaderVar& inQuadEdge = args.fGP.cast<QuadEdgeEffect>().inQuadEdge();
|
const GrShaderVar& inQuadEdge = args.fGP.cast<QuadEdgeEffect>().inQuadEdge();
|
||||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||||
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), inQuadEdge.c_str());
|
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), inQuadEdge.c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
|
|
||||||
vsBuilder->uViewM(), vsBuilder->inPosition());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
|
static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
|
||||||
|
@ -14,6 +14,251 @@
|
|||||||
#include "SkColorPriv.h"
|
#include "SkColorPriv.h"
|
||||||
#include "GrGeometryProcessor.h"
|
#include "GrGeometryProcessor.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
class GrGLAlignedRectEffect;
|
||||||
|
|
||||||
|
// Axis Aligned special case
|
||||||
|
class GrAlignedRectEffect : public GrGeometryProcessor {
|
||||||
|
public:
|
||||||
|
static GrGeometryProcessor* Create() {
|
||||||
|
GR_CREATE_STATIC_PROCESSOR(gAlignedRectEffect, GrAlignedRectEffect, ());
|
||||||
|
gAlignedRectEffect->ref();
|
||||||
|
return gAlignedRectEffect;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~GrAlignedRectEffect() {}
|
||||||
|
|
||||||
|
static const char* Name() { return "AlignedRectEdge"; }
|
||||||
|
|
||||||
|
const GrShaderVar& inRect() const { return fInRect; }
|
||||||
|
|
||||||
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
||||||
|
return GrTBackendGeometryProcessorFactory<GrAlignedRectEffect>::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
class GLProcessor : public GrGLGeometryProcessor {
|
||||||
|
public:
|
||||||
|
GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
|
||||||
|
: INHERITED (factory) {}
|
||||||
|
|
||||||
|
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
|
||||||
|
// setup the varying for the Axis aligned rect effect
|
||||||
|
// xy -> interpolated offset
|
||||||
|
// zw -> w/2+0.5, h/2+0.5
|
||||||
|
GrGLVertToFrag v(kVec4f_GrSLType);
|
||||||
|
args.fPB->addVarying("Rect", &v);
|
||||||
|
|
||||||
|
const GrShaderVar& inRect = args.fGP.cast<GrAlignedRectEffect>().inRect();
|
||||||
|
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||||
|
vsBuilder->codeAppendf("\t%s = %s;\n", v.fsIn(), inRect.c_str());
|
||||||
|
|
||||||
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
|
// TODO: compute all these offsets, spans, and scales in the VS
|
||||||
|
fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", v.fsIn());
|
||||||
|
fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", v.fsIn());
|
||||||
|
fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
|
||||||
|
// For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
|
||||||
|
// < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
|
||||||
|
fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
|
||||||
|
fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
|
||||||
|
// For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
|
||||||
|
// value of coverage that is used. In other words it is the coverage that is
|
||||||
|
// used in the interior of the rect after the ramp.
|
||||||
|
fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
|
||||||
|
fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
|
||||||
|
|
||||||
|
// Compute the coverage for the rect's width
|
||||||
|
fsBuilder->codeAppendf(
|
||||||
|
"\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.0);\n", v.fsIn(),
|
||||||
|
v.fsIn());
|
||||||
|
// Compute the coverage for the rect's height and merge with the width
|
||||||
|
fsBuilder->codeAppendf(
|
||||||
|
"\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0, 1.0);\n",
|
||||||
|
v.fsIn(), v.fsIn());
|
||||||
|
|
||||||
|
|
||||||
|
fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
|
||||||
|
(GrGLSLExpr4(args.fInput) * GrGLSLExpr1("coverage")).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
|
||||||
|
|
||||||
|
virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef GrGLGeometryProcessor INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
GrAlignedRectEffect()
|
||||||
|
: fInRect(this->addVertexAttrib(GrShaderVar("inRect",
|
||||||
|
kVec4f_GrSLType,
|
||||||
|
GrShaderVar::kAttribute_TypeModifier))) {
|
||||||
|
}
|
||||||
|
|
||||||
|
const GrShaderVar& fInRect;
|
||||||
|
|
||||||
|
virtual bool onIsEqual(const GrGeometryProcessor&) const SK_OVERRIDE { return true; }
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
|
||||||
|
inout->mulByUnknownAlpha();
|
||||||
|
}
|
||||||
|
|
||||||
|
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
|
||||||
|
|
||||||
|
typedef GrGeometryProcessor INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrAlignedRectEffect);
|
||||||
|
|
||||||
|
GrGeometryProcessor* GrAlignedRectEffect::TestCreate(SkRandom* random,
|
||||||
|
GrContext* context,
|
||||||
|
const GrDrawTargetCaps&,
|
||||||
|
GrTexture* textures[]) {
|
||||||
|
return GrAlignedRectEffect::Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
class GrGLRectEffect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The output of this effect is a modulation of the input color and coverage
|
||||||
|
* for an arbitrarily oriented rect. The rect is specified as:
|
||||||
|
* Center of the rect
|
||||||
|
* Unit vector point down the height of the rect
|
||||||
|
* Half width + 0.5
|
||||||
|
* Half height + 0.5
|
||||||
|
* The center and vector are stored in a vec4 varying ("RectEdge") with the
|
||||||
|
* center in the xy components and the vector in the zw components.
|
||||||
|
* The munged width and height are stored in a vec2 varying ("WidthHeight")
|
||||||
|
* with the width in x and the height in y.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class GrRectEffect : public GrGeometryProcessor {
|
||||||
|
public:
|
||||||
|
static GrGeometryProcessor* Create() {
|
||||||
|
GR_CREATE_STATIC_PROCESSOR(gRectEffect, GrRectEffect, ());
|
||||||
|
gRectEffect->ref();
|
||||||
|
return gRectEffect;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~GrRectEffect() {}
|
||||||
|
|
||||||
|
static const char* Name() { return "RectEdge"; }
|
||||||
|
|
||||||
|
const GrShaderVar& inRectEdge() const { return fInRectEdge; }
|
||||||
|
const GrShaderVar& inWidthHeight() const { return fInWidthHeight; }
|
||||||
|
|
||||||
|
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
||||||
|
return GrTBackendGeometryProcessorFactory<GrRectEffect>::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
class GLProcessor : public GrGLGeometryProcessor {
|
||||||
|
public:
|
||||||
|
GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
|
||||||
|
: INHERITED (factory) {}
|
||||||
|
|
||||||
|
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
|
||||||
|
// setup the varying for the center point and the unit vector
|
||||||
|
// that points down the height of the rect
|
||||||
|
GrGLVertToFrag rectEdge(kVec4f_GrSLType);
|
||||||
|
args.fPB->addVarying("RectEdge", &rectEdge);
|
||||||
|
|
||||||
|
const GrRectEffect& rectEffect = args.fGP.cast<GrRectEffect>();
|
||||||
|
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||||
|
vsBuilder->codeAppendf("%s = %s;", rectEdge.vsOut(), rectEffect.inRectEdge().c_str());
|
||||||
|
|
||||||
|
// setup the varying for width/2+.5 and height/2+.5
|
||||||
|
GrGLVertToFrag widthHeight(kVec2f_GrSLType);
|
||||||
|
args.fPB->addVarying("WidthHeight", &widthHeight);
|
||||||
|
vsBuilder->codeAppendf("%s = %s;",
|
||||||
|
widthHeight.vsOut(),
|
||||||
|
rectEffect.inWidthHeight().c_str());
|
||||||
|
|
||||||
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
|
// TODO: compute all these offsets, spans, and scales in the VS
|
||||||
|
fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", widthHeight.fsIn());
|
||||||
|
fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", widthHeight.fsIn());
|
||||||
|
fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
|
||||||
|
// For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
|
||||||
|
// < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
|
||||||
|
fsBuilder->codeAppend("\tfloat spanW = insetW + outset;\n");
|
||||||
|
fsBuilder->codeAppend("\tfloat spanH = insetH + outset;\n");
|
||||||
|
// For rects < 1 pixel wide or tall, these scale factors are used to cap the maximum
|
||||||
|
// value of coverage that is used. In other words it is the coverage that is
|
||||||
|
// used in the interior of the rect after the ramp.
|
||||||
|
fsBuilder->codeAppend("\tfloat scaleW = min(1.0, 2.0*insetW/spanW);\n");
|
||||||
|
fsBuilder->codeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
|
||||||
|
|
||||||
|
// Compute the coverage for the rect's width
|
||||||
|
fsBuilder->codeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
|
||||||
|
fsBuilder->fragmentPosition(), rectEdge.fsIn());
|
||||||
|
fsBuilder->codeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
|
||||||
|
rectEdge.fsIn(), rectEdge.fsIn());
|
||||||
|
fsBuilder->codeAppendf(
|
||||||
|
"\tfloat coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0);\n",
|
||||||
|
widthHeight.fsIn());
|
||||||
|
|
||||||
|
// Compute the coverage for the rect's height and merge with the width
|
||||||
|
fsBuilder->codeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
|
||||||
|
rectEdge.fsIn());
|
||||||
|
fsBuilder->codeAppendf(
|
||||||
|
"\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.0, 1.0);\n",
|
||||||
|
widthHeight.fsIn());
|
||||||
|
|
||||||
|
|
||||||
|
fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
|
||||||
|
(GrGLSLExpr4(args.fInput) * GrGLSLExpr1("coverage")).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
|
||||||
|
|
||||||
|
virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) SK_OVERRIDE {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef GrGLGeometryProcessor INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
GrRectEffect()
|
||||||
|
: fInRectEdge(this->addVertexAttrib(GrShaderVar("inRectEdge",
|
||||||
|
kVec4f_GrSLType,
|
||||||
|
GrShaderVar::kAttribute_TypeModifier)))
|
||||||
|
, fInWidthHeight(this->addVertexAttrib(
|
||||||
|
GrShaderVar("inWidthHeight",
|
||||||
|
kVec2f_GrSLType,
|
||||||
|
GrShaderVar::kAttribute_TypeModifier))) {
|
||||||
|
this->setWillReadFragmentPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool onIsEqual(const GrGeometryProcessor&) const SK_OVERRIDE { return true; }
|
||||||
|
|
||||||
|
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
|
||||||
|
inout->mulByUnknownAlpha();
|
||||||
|
}
|
||||||
|
|
||||||
|
const GrShaderVar& fInRectEdge;
|
||||||
|
const GrShaderVar& fInWidthHeight;
|
||||||
|
|
||||||
|
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
|
||||||
|
|
||||||
|
typedef GrGeometryProcessor INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRectEffect);
|
||||||
|
|
||||||
|
GrGeometryProcessor* GrRectEffect::TestCreate(SkRandom* random,
|
||||||
|
GrContext* context,
|
||||||
|
const GrDrawTargetCaps&,
|
||||||
|
GrTexture* textures[]) {
|
||||||
|
return GrRectEffect::Create();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -303,6 +548,155 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
|
|||||||
target->resetIndexSource();
|
target->resetIndexSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Rotated
|
||||||
|
struct RectVertex {
|
||||||
|
SkPoint fPos;
|
||||||
|
SkPoint fCenter;
|
||||||
|
SkPoint fDir;
|
||||||
|
SkPoint fWidthHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rotated
|
||||||
|
extern const GrVertexAttrib gAARectVertexAttribs[] = {
|
||||||
|
{ kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
|
||||||
|
{ kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding },
|
||||||
|
{ kVec2f_GrVertexAttribType, 3*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Axis Aligned
|
||||||
|
struct AARectVertex {
|
||||||
|
SkPoint fPos;
|
||||||
|
SkPoint fOffset;
|
||||||
|
SkPoint fWidthHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Axis Aligned
|
||||||
|
extern const GrVertexAttrib gAAAARectVertexAttribs[] = {
|
||||||
|
{ kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
|
||||||
|
{ kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding },
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void GrAARectRenderer::shaderFillAARect(GrDrawTarget* target,
|
||||||
|
const SkRect& rect,
|
||||||
|
const SkMatrix& combinedMatrix) {
|
||||||
|
GrDrawState* drawState = target->drawState();
|
||||||
|
|
||||||
|
SkPoint center = SkPoint::Make(rect.centerX(), rect.centerY());
|
||||||
|
combinedMatrix.mapPoints(¢er, 1);
|
||||||
|
|
||||||
|
// compute transformed (0, 1) vector
|
||||||
|
SkVector dir = { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScaleY] };
|
||||||
|
dir.normalize();
|
||||||
|
|
||||||
|
// compute transformed (width, 0) and (0, height) vectors
|
||||||
|
SkVector vec[2] = {
|
||||||
|
{ combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY] },
|
||||||
|
{ combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScaleY] }
|
||||||
|
};
|
||||||
|
|
||||||
|
SkScalar newWidth = SkScalarHalf(rect.width() * vec[0].length()) + SK_ScalarHalf;
|
||||||
|
SkScalar newHeight = SkScalarHalf(rect.height() * vec[1].length()) + SK_ScalarHalf;
|
||||||
|
drawState->setVertexAttribs<gAARectVertexAttribs>(SK_ARRAY_COUNT(gAARectVertexAttribs),
|
||||||
|
sizeof(RectVertex));
|
||||||
|
|
||||||
|
GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
|
||||||
|
if (!geo.succeeded()) {
|
||||||
|
SkDebugf("Failed to get space for vertices!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RectVertex* verts = reinterpret_cast<RectVertex*>(geo.vertices());
|
||||||
|
|
||||||
|
GrGeometryProcessor* gp = GrRectEffect::Create();
|
||||||
|
drawState->setGeometryProcessor(gp)->unref();
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
verts[i].fCenter = center;
|
||||||
|
verts[i].fDir = dir;
|
||||||
|
verts[i].fWidthHeight.fX = newWidth;
|
||||||
|
verts[i].fWidthHeight.fY = newHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkRect devRect;
|
||||||
|
combinedMatrix.mapRect(&devRect, rect);
|
||||||
|
|
||||||
|
SkRect devBounds = {
|
||||||
|
devRect.fLeft - SK_ScalarHalf,
|
||||||
|
devRect.fTop - SK_ScalarHalf,
|
||||||
|
devRect.fRight + SK_ScalarHalf,
|
||||||
|
devRect.fBottom + SK_ScalarHalf
|
||||||
|
};
|
||||||
|
|
||||||
|
verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
|
||||||
|
verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
|
||||||
|
verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
|
||||||
|
verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
|
||||||
|
|
||||||
|
target->setIndexSourceToBuffer(fGpu->getContext()->getQuadIndexBuffer());
|
||||||
|
target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
|
||||||
|
target->resetIndexSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrAARectRenderer::shaderFillAlignedAARect(GrDrawTarget* target,
|
||||||
|
const SkRect& rect,
|
||||||
|
const SkMatrix& combinedMatrix) {
|
||||||
|
GrDrawState* drawState = target->drawState();
|
||||||
|
SkASSERT(combinedMatrix.rectStaysRect());
|
||||||
|
|
||||||
|
drawState->setVertexAttribs<gAAAARectVertexAttribs>(SK_ARRAY_COUNT(gAAAARectVertexAttribs),
|
||||||
|
sizeof(AARectVertex));
|
||||||
|
|
||||||
|
GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
|
||||||
|
if (!geo.succeeded()) {
|
||||||
|
SkDebugf("Failed to get space for vertices!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AARectVertex* verts = reinterpret_cast<AARectVertex*>(geo.vertices());
|
||||||
|
|
||||||
|
GrGeometryProcessor* gp = GrAlignedRectEffect::Create();
|
||||||
|
drawState->setGeometryProcessor(gp)->unref();
|
||||||
|
|
||||||
|
SkRect devRect;
|
||||||
|
combinedMatrix.mapRect(&devRect, rect);
|
||||||
|
|
||||||
|
SkRect devBounds = {
|
||||||
|
devRect.fLeft - SK_ScalarHalf,
|
||||||
|
devRect.fTop - SK_ScalarHalf,
|
||||||
|
devRect.fRight + SK_ScalarHalf,
|
||||||
|
devRect.fBottom + SK_ScalarHalf
|
||||||
|
};
|
||||||
|
|
||||||
|
SkPoint widthHeight = {
|
||||||
|
SkScalarHalf(devRect.width()) + SK_ScalarHalf,
|
||||||
|
SkScalarHalf(devRect.height()) + SK_ScalarHalf
|
||||||
|
};
|
||||||
|
|
||||||
|
verts[0].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fTop);
|
||||||
|
verts[0].fOffset = SkPoint::Make(-widthHeight.fX, -widthHeight.fY);
|
||||||
|
verts[0].fWidthHeight = widthHeight;
|
||||||
|
|
||||||
|
verts[1].fPos = SkPoint::Make(devBounds.fLeft, devBounds.fBottom);
|
||||||
|
verts[1].fOffset = SkPoint::Make(-widthHeight.fX, widthHeight.fY);
|
||||||
|
verts[1].fWidthHeight = widthHeight;
|
||||||
|
|
||||||
|
verts[2].fPos = SkPoint::Make(devBounds.fRight, devBounds.fBottom);
|
||||||
|
verts[2].fOffset = widthHeight;
|
||||||
|
verts[2].fWidthHeight = widthHeight;
|
||||||
|
|
||||||
|
verts[3].fPos = SkPoint::Make(devBounds.fRight, devBounds.fTop);
|
||||||
|
verts[3].fOffset = SkPoint::Make(widthHeight.fX, -widthHeight.fY);
|
||||||
|
verts[3].fWidthHeight = widthHeight;
|
||||||
|
|
||||||
|
target->setIndexSourceToBuffer(fGpu->getContext()->getQuadIndexBuffer());
|
||||||
|
target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6);
|
||||||
|
target->resetIndexSource();
|
||||||
|
}
|
||||||
|
|
||||||
void GrAARectRenderer::strokeAARect(GrDrawTarget* target,
|
void GrAARectRenderer::strokeAARect(GrDrawTarget* target,
|
||||||
const SkRect& rect,
|
const SkRect& rect,
|
||||||
const SkMatrix& combinedMatrix,
|
const SkMatrix& combinedMatrix,
|
||||||
|
@ -44,7 +44,17 @@ public:
|
|||||||
const SkRect& rect,
|
const SkRect& rect,
|
||||||
const SkMatrix& combinedMatrix,
|
const SkMatrix& combinedMatrix,
|
||||||
const SkRect& devRect) {
|
const SkRect& devRect) {
|
||||||
|
#ifdef SHADER_AA_FILL_RECT
|
||||||
|
if (combinedMatrix.rectStaysRect()) {
|
||||||
|
this->shaderFillAlignedAARect(gpu, target,
|
||||||
|
rect, combinedMatrix);
|
||||||
|
} else {
|
||||||
|
this->shaderFillAARect(gpu, target,
|
||||||
|
rect, combinedMatrix);
|
||||||
|
}
|
||||||
|
#else
|
||||||
this->geometryFillAARect(target, rect, combinedMatrix, devRect);
|
this->geometryFillAARect(target, rect, combinedMatrix, devRect);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void strokeAARect(GrDrawTarget* target,
|
void strokeAARect(GrDrawTarget* target,
|
||||||
@ -66,6 +76,14 @@ private:
|
|||||||
const SkMatrix& combinedMatrix,
|
const SkMatrix& combinedMatrix,
|
||||||
const SkRect& devRect);
|
const SkRect& devRect);
|
||||||
|
|
||||||
|
void shaderFillAARect(GrDrawTarget* target,
|
||||||
|
const SkRect& rect,
|
||||||
|
const SkMatrix& combinedMatrix);
|
||||||
|
|
||||||
|
void shaderFillAlignedAARect(GrDrawTarget* target,
|
||||||
|
const SkRect& rect,
|
||||||
|
const SkMatrix& combinedMatrix);
|
||||||
|
|
||||||
void geometryStrokeAARect(GrDrawTarget* target,
|
void geometryStrokeAARect(GrDrawTarget* target,
|
||||||
const SkRect& devOutside,
|
const SkRect& devOutside,
|
||||||
const SkRect& devOutsideAssist,
|
const SkRect& devOutsideAssist,
|
||||||
|
@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2014 Google Inc.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license that can be
|
|
||||||
* found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "GrDefaultGeoProcFactory.h"
|
|
||||||
|
|
||||||
#include "gl/builders/GrGLProgramBuilder.h"
|
|
||||||
#include "gl/GrGLGeometryProcessor.h"
|
|
||||||
#include "GrDrawState.h"
|
|
||||||
#include "GrTBackendProcessorFactory.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The default Geometry Processor simply takes position and multiplies it by the uniform view
|
|
||||||
* matrix. It also leaves coverage untouched. Behind the scenes, we may add per vertex color or
|
|
||||||
* local coords.
|
|
||||||
*/
|
|
||||||
class DefaultGeoProc : public GrGeometryProcessor {
|
|
||||||
public:
|
|
||||||
static GrGeometryProcessor* Create() {
|
|
||||||
GR_CREATE_STATIC_PROCESSOR(gDefaultGeoProc, DefaultGeoProc, ());
|
|
||||||
return SkRef(gDefaultGeoProc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* Name() { return "DefaultGeometryProcessor"; }
|
|
||||||
|
|
||||||
virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE {
|
|
||||||
return GrTBackendGeometryProcessorFactory<DefaultGeoProc>::getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
class GLProcessor : public GrGLGeometryProcessor {
|
|
||||||
public:
|
|
||||||
GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
|
|
||||||
: INHERITED (factory) {}
|
|
||||||
|
|
||||||
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
|
|
||||||
GrGLVertexBuilder* vs = args.fPB->getVertexShaderBuilder();
|
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vs->codeAppendf("%s = %s * vec3(%s, 1);", vs->glPosition(), vs->uViewM(),
|
|
||||||
vs->inPosition());
|
|
||||||
|
|
||||||
// output coverage in FS(pass through)
|
|
||||||
GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
|
|
||||||
fs->codeAppendf("%s = %s;", args.fOutput, GrGLSLExpr4(args.fInput).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
|
|
||||||
|
|
||||||
virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef GrGLGeometryProcessor INHERITED;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
DefaultGeoProc() {}
|
|
||||||
|
|
||||||
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
|
|
||||||
inout->mulByUnknownAlpha();
|
|
||||||
}
|
|
||||||
|
|
||||||
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
|
|
||||||
|
|
||||||
typedef GrFragmentProcessor INHERITED;
|
|
||||||
};
|
|
||||||
|
|
||||||
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc);
|
|
||||||
|
|
||||||
GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random,
|
|
||||||
GrContext*,
|
|
||||||
const GrDrawTargetCaps& caps,
|
|
||||||
GrTexture*[]) {
|
|
||||||
return DefaultGeoProc::Create();
|
|
||||||
}
|
|
||||||
|
|
||||||
// We use these arrays to customize our default GP. We only need 4 because we omit coverage if
|
|
||||||
// coverage is not requested in the flags to the create function.
|
|
||||||
GrVertexAttrib kDefaultPositionGeoProc[] = {
|
|
||||||
{ kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
|
|
||||||
{ kVec4ub_GrVertexAttribType, sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
|
|
||||||
};
|
|
||||||
|
|
||||||
GrVertexAttrib kDefaultPosColorGeoProc[] = {
|
|
||||||
{ kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
|
|
||||||
{ kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding },
|
|
||||||
{ kVec4ub_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
|
|
||||||
};
|
|
||||||
|
|
||||||
GrVertexAttrib kDefaultPosUVGeoProc[] = {
|
|
||||||
{ kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
|
|
||||||
{ kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding },
|
|
||||||
{ kVec4ub_GrVertexAttribType, 2 * sizeof(SkPoint), kCoverage_GrVertexAttribBinding },
|
|
||||||
};
|
|
||||||
|
|
||||||
GrVertexAttrib kDefaultPosColUVGeoProc[] = {
|
|
||||||
{ kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
|
|
||||||
{ kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding },
|
|
||||||
{ kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kLocalCoord_GrVertexAttribBinding },
|
|
||||||
{ kVec4ub_GrVertexAttribType, 2 * sizeof(SkPoint) + sizeof(GrColor), kCoverage_GrVertexAttribBinding },
|
|
||||||
};
|
|
||||||
|
|
||||||
static size_t get_size(GrDefaultGeoProcFactory::GPType flag) {
|
|
||||||
switch (flag) {
|
|
||||||
case GrDefaultGeoProcFactory::kPosition_GPType:
|
|
||||||
return GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
|
|
||||||
case GrDefaultGeoProcFactory::kColor_GPType:
|
|
||||||
return GrVertexAttribTypeSize(kVec4ub_GrVertexAttribType);
|
|
||||||
case GrDefaultGeoProcFactory::kLocalCoord_GPType:
|
|
||||||
return GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
|
|
||||||
case GrDefaultGeoProcFactory::kCoverage_GPType:
|
|
||||||
return GrVertexAttribTypeSize(kVec4ub_GrVertexAttribType);
|
|
||||||
default:
|
|
||||||
SkFAIL("Should never get here");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const GrGeometryProcessor*
|
|
||||||
GrDefaultGeoProcFactory::CreateAndSetAttribs(GrDrawState* ds, uint32_t gpTypeFlags) {
|
|
||||||
SkASSERT(ds);
|
|
||||||
// always atleast position in the GP
|
|
||||||
size_t size = get_size(kPosition_GPType);
|
|
||||||
int count = 1;
|
|
||||||
|
|
||||||
bool hasColor = SkToBool(gpTypeFlags & kColor_GPType);
|
|
||||||
bool hasLocalCoord = SkToBool(gpTypeFlags & kLocalCoord_GPType);
|
|
||||||
bool hasCoverage = SkToBool(gpTypeFlags & kCoverage_GPType);
|
|
||||||
|
|
||||||
if (hasColor) {
|
|
||||||
size += get_size(kColor_GPType);
|
|
||||||
count++;
|
|
||||||
if (hasLocalCoord) {
|
|
||||||
size += get_size(kLocalCoord_GPType);
|
|
||||||
count++;
|
|
||||||
if (hasCoverage) {
|
|
||||||
size += get_size(kCoverage_GPType);
|
|
||||||
count++;
|
|
||||||
ds->setVertexAttribs<kDefaultPosColUVGeoProc>(count, size);
|
|
||||||
} else {
|
|
||||||
ds->setVertexAttribs<kDefaultPosColUVGeoProc>(count, size);
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (hasCoverage) {
|
|
||||||
size += get_size(kCoverage_GPType);
|
|
||||||
count++;
|
|
||||||
ds->setVertexAttribs<kDefaultPosColorGeoProc>(count, size);
|
|
||||||
} else {
|
|
||||||
ds->setVertexAttribs<kDefaultPosColorGeoProc>(count, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (hasLocalCoord) {
|
|
||||||
size += get_size(kLocalCoord_GPType);
|
|
||||||
count++;
|
|
||||||
if (hasCoverage) {
|
|
||||||
size += get_size(kCoverage_GPType);
|
|
||||||
count++;
|
|
||||||
ds->setVertexAttribs<kDefaultPosUVGeoProc>(count, size);
|
|
||||||
} else {
|
|
||||||
ds->setVertexAttribs<kDefaultPosUVGeoProc>(count, size);
|
|
||||||
}
|
|
||||||
} else if (hasCoverage) {
|
|
||||||
size += get_size(kCoverage_GPType);
|
|
||||||
count++;
|
|
||||||
ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size);
|
|
||||||
} else {
|
|
||||||
// Just position
|
|
||||||
ds->setVertexAttribs<kDefaultPositionGeoProc>(count, size);
|
|
||||||
}
|
|
||||||
return DefaultGeoProc::Create();
|
|
||||||
}
|
|
||||||
|
|
||||||
const GrGeometryProcessor* GrDefaultGeoProcFactory::Create() {
|
|
||||||
return DefaultGeoProc::Create();
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2014 Google Inc.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license that can be
|
|
||||||
* found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GrDefaultGeoProcFactory_DEFINED
|
|
||||||
#define GrDefaultGeoProcFactory_DEFINED
|
|
||||||
|
|
||||||
#include "GrGeometryProcessor.h"
|
|
||||||
|
|
||||||
class GrDrawState;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A factory for creating default Geometry Processors which simply multiply position by the uniform
|
|
||||||
* view matrix and wire through color, coverage, UV coords if requested. Right now this is only
|
|
||||||
* used in the creation of optimized draw states because adding default GPs to the drawstate can
|
|
||||||
* interfere with batching due to updating the drawstate.
|
|
||||||
* TODO When we track geometry state separately from the draw state, we should be able use a default
|
|
||||||
* GP with every draw call
|
|
||||||
*/
|
|
||||||
class GrDefaultGeoProcFactory {
|
|
||||||
public:
|
|
||||||
// Structs for adding vertex attributes
|
|
||||||
struct PositionAttr {
|
|
||||||
SkPoint fPosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PositionCoverageAttr {
|
|
||||||
SkPoint fPosition;
|
|
||||||
GrColor fCoverage;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PositionColorAttr {
|
|
||||||
SkPoint fPosition;
|
|
||||||
SkColor fColor;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PositionColorCoverageAttr {
|
|
||||||
SkPoint fPosition;
|
|
||||||
SkColor fColor;
|
|
||||||
GrColor fCoverage;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PositionLocalCoordAttr {
|
|
||||||
SkPoint fPosition;
|
|
||||||
SkPoint fLocalCoord;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PositionLocalCoordCoverageAttr {
|
|
||||||
SkPoint fPosition;
|
|
||||||
SkPoint fLocalCoord;
|
|
||||||
GrColor fCoverage;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PositionColorLocalCoordAttr {
|
|
||||||
SkPoint fPosition;
|
|
||||||
GrColor fColor;
|
|
||||||
SkPoint fLocalCoord;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PositionColorLocalCoordCoverage {
|
|
||||||
SkPoint fPosition;
|
|
||||||
GrColor fColor;
|
|
||||||
SkPoint fLocalCoord;
|
|
||||||
GrColor fCoverage;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GPType {
|
|
||||||
kPosition_GPType = 0x0, // we ALWAYS have position
|
|
||||||
kColor_GPType = 0x01,
|
|
||||||
kLocalCoord_GPType = 0x02,
|
|
||||||
kCoverage_GPType= 0x04,
|
|
||||||
kLastGPType = kCoverage_GPType
|
|
||||||
};
|
|
||||||
|
|
||||||
// YOU MUST UNREF
|
|
||||||
static const GrGeometryProcessor* CreateAndSetAttribs(GrDrawState*, uint32_t GPTypeFlags);
|
|
||||||
static const GrGeometryProcessor* Create();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -7,10 +7,9 @@
|
|||||||
|
|
||||||
#include "GrOptDrawState.h"
|
#include "GrOptDrawState.h"
|
||||||
|
|
||||||
#include "GrDefaultGeoProcFactory.h"
|
|
||||||
#include "GrDrawState.h"
|
#include "GrDrawState.h"
|
||||||
#include "GrDrawTargetCaps.h"
|
#include "GrDrawTargetCaps.h"
|
||||||
#include "GrGpu.h"
|
#include "gl/GrGpuGL.h"
|
||||||
|
|
||||||
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
||||||
BlendOptFlags blendOptFlags,
|
BlendOptFlags blendOptFlags,
|
||||||
@ -64,10 +63,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
|||||||
// Copy GeometryProcesssor from DS or ODS
|
// Copy GeometryProcesssor from DS or ODS
|
||||||
if (drawState.hasGeometryProcessor()) {
|
if (drawState.hasGeometryProcessor()) {
|
||||||
fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
|
fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
|
||||||
} else if (!GrGpu::IsPathRenderingDrawType(drawType)) {
|
|
||||||
// Install default GP, this will be ignored if we are rendering with fragment shader only
|
|
||||||
// TODO(joshualitt) rendering code should do this
|
|
||||||
fGeometryProcessor.reset(GrDefaultGeoProcFactory::Create());
|
|
||||||
} else {
|
} else {
|
||||||
fGeometryProcessor.reset(NULL);
|
fGeometryProcessor.reset(NULL);
|
||||||
}
|
}
|
||||||
|
@ -100,10 +100,6 @@ public:
|
|||||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();;
|
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();;
|
||||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), circleEffect.inCircleEdge().c_str());
|
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), circleEffect.inCircleEdge().c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
|
|
||||||
vsBuilder->uViewM(), vsBuilder->inPosition());
|
|
||||||
|
|
||||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
|
fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
|
||||||
fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z - d, 0.0, 1.0);", v.fsIn());
|
fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z - d, 0.0, 1.0);", v.fsIn());
|
||||||
@ -223,10 +219,6 @@ public:
|
|||||||
vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
|
vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
|
||||||
ellipseEffect.inEllipseRadii().c_str());
|
ellipseEffect.inEllipseRadii().c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
|
|
||||||
vsBuilder->uViewM(), vsBuilder->inPosition());
|
|
||||||
|
|
||||||
// for outer curve
|
// for outer curve
|
||||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
|
fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
|
||||||
@ -373,10 +365,6 @@ public:
|
|||||||
vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
|
vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
|
||||||
ellipseEffect.inEllipseOffsets1().c_str());
|
ellipseEffect.inEllipseOffsets1().c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
|
|
||||||
vsBuilder->uViewM(), vsBuilder->inPosition());
|
|
||||||
|
|
||||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
SkAssertResult(fsBuilder->enableFeature(
|
SkAssertResult(fsBuilder->enableFeature(
|
||||||
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||||
|
@ -38,7 +38,7 @@ GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
|
|||||||
* manually adjusted.
|
* manually adjusted.
|
||||||
*/
|
*/
|
||||||
static const int kFPFactoryCount = 37;
|
static const int kFPFactoryCount = 37;
|
||||||
static const int kGPFactoryCount = 14;
|
static const int kGPFactoryCount = 15;
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
|
void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
|
||||||
|
@ -44,10 +44,6 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
|
|||||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inConicCoeffs.c_str());
|
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inConicCoeffs.c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
|
|
||||||
vsBuilder->inPosition());
|
|
||||||
|
|
||||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
fsBuilder->codeAppend("float edgeAlpha;");
|
fsBuilder->codeAppend("float edgeAlpha;");
|
||||||
|
|
||||||
@ -188,10 +184,6 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
|
|||||||
const GrShaderVar& inHairQuadEdge = args.fGP.cast<GrQuadEffect>().inHairQuadEdge();
|
const GrShaderVar& inHairQuadEdge = args.fGP.cast<GrQuadEffect>().inHairQuadEdge();
|
||||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inHairQuadEdge.c_str());
|
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inHairQuadEdge.c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
|
|
||||||
vsBuilder->inPosition());
|
|
||||||
|
|
||||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
fsBuilder->codeAppendf("float edgeAlpha;");
|
fsBuilder->codeAppendf("float edgeAlpha;");
|
||||||
|
|
||||||
@ -318,10 +310,6 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
|
|||||||
const GrShaderVar& inCubicCoeffs = args.fGP.cast<GrCubicEffect>().inCubicCoeffs();
|
const GrShaderVar& inCubicCoeffs = args.fGP.cast<GrCubicEffect>().inCubicCoeffs();
|
||||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inCubicCoeffs.c_str());
|
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inCubicCoeffs.c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
|
|
||||||
vsBuilder->inPosition());
|
|
||||||
|
|
||||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
|
|
||||||
GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
|
GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
|
||||||
|
@ -31,10 +31,6 @@ public:
|
|||||||
const GrShaderVar& inTextureCoords = customCoordsTextureEffect.inTextureCoords();
|
const GrShaderVar& inTextureCoords = customCoordsTextureEffect.inTextureCoords();
|
||||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inTextureCoords.c_str());
|
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inTextureCoords.c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
|
|
||||||
vsBuilder->uViewM(), vsBuilder->inPosition());
|
|
||||||
|
|
||||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
fsBuilder->codeAppendf("%s = ", args.fOutput);
|
fsBuilder->codeAppendf("%s = ", args.fOutput);
|
||||||
fsBuilder->appendTextureLookupAndModulate(args.fInput,
|
fsBuilder->appendTextureLookupAndModulate(args.fInput,
|
||||||
|
@ -520,10 +520,6 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) {
|
|||||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||||
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dce.inCoord().c_str());
|
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dce.inCoord().c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
|
|
||||||
vsBuilder->inPosition());
|
|
||||||
|
|
||||||
// transforms all points so that we can compare them to our test circle
|
// transforms all points so that we can compare them to our test circle
|
||||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n",
|
fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n",
|
||||||
@ -727,10 +723,6 @@ void GLDashingLineEffect::emitCode(const EmitArgs& args) {
|
|||||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||||
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), de.inCoord().c_str());
|
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), de.inCoord().c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
|
|
||||||
vsBuilder->inPosition());
|
|
||||||
|
|
||||||
// transforms all points so that we can compare them to our test rect
|
// transforms all points so that we can compare them to our test rect
|
||||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||||
fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
|
fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
|
||||||
|
@ -45,10 +45,6 @@ public:
|
|||||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||||
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
|
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
|
|
||||||
vsBuilder->uViewM(), vsBuilder->inPosition());
|
|
||||||
|
|
||||||
const char* textureSizeUniName = NULL;
|
const char* textureSizeUniName = NULL;
|
||||||
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
||||||
kVec2f_GrSLType, "TextureSize",
|
kVec2f_GrSLType, "TextureSize",
|
||||||
@ -260,10 +256,6 @@ public:
|
|||||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
|
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
|
|
||||||
vsBuilder->uViewM(), vsBuilder->inPosition());
|
|
||||||
|
|
||||||
const char* textureSizeUniName = NULL;
|
const char* textureSizeUniName = NULL;
|
||||||
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
||||||
kVec2f_GrSLType, "TextureSize",
|
kVec2f_GrSLType, "TextureSize",
|
||||||
@ -418,10 +410,6 @@ public:
|
|||||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||||
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
|
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
|
||||||
|
|
||||||
// setup position varying
|
|
||||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
|
|
||||||
vsBuilder->uViewM(), vsBuilder->inPosition());
|
|
||||||
|
|
||||||
const char* textureSizeUniName = NULL;
|
const char* textureSizeUniName = NULL;
|
||||||
// width, height, 1/(3*width)
|
// width, height, 1/(3*width)
|
||||||
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
||||||
|
@ -106,10 +106,6 @@ public:
|
|||||||
return fExpr.c_str();
|
return fExpr.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValid() const {
|
|
||||||
return kFullExpr_ExprType != fType || !fExpr.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Constructs an invalid expression.
|
/** Constructs an invalid expression.
|
||||||
* Useful only as a return value from functions that never actually return
|
* Useful only as a return value from functions that never actually return
|
||||||
@ -170,6 +166,10 @@ protected:
|
|||||||
fExpr.appendf(format, in0, in1);
|
fExpr.appendf(format, in0, in1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isValid() const {
|
||||||
|
return kFullExpr_ExprType != fType || !fExpr.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns expression casted to another type.
|
/** Returns expression casted to another type.
|
||||||
* Generic implementation that is called for non-trivial cases of casts. */
|
* Generic implementation that is called for non-trivial cases of casts. */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -57,11 +57,9 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
|
|||||||
bool hasVertexShader = !(header.fUseNvpr &&
|
bool hasVertexShader = !(header.fUseNvpr &&
|
||||||
gpu->glPathRendering()->texturingMode() ==
|
gpu->glPathRendering()->texturingMode() ==
|
||||||
GrGLPathRendering::FixedFunction_TexturingMode);
|
GrGLPathRendering::FixedFunction_TexturingMode);
|
||||||
|
|
||||||
if (hasVertexShader) {
|
if (hasVertexShader) {
|
||||||
pb->fVS.setupUniformViewMatrix();
|
pb->fVS.setupLocalCoords();
|
||||||
pb->fVS.setupPositionAndLocalCoords();
|
pb->fVS.transformGLToSkiaCoords();
|
||||||
|
|
||||||
if (header.fEmitsPointSize) {
|
if (header.fEmitsPointSize) {
|
||||||
pb->fVS.codeAppend("gl_PointSize = 1.0;");
|
pb->fVS.codeAppend("gl_PointSize = 1.0;");
|
||||||
}
|
}
|
||||||
@ -77,10 +75,10 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
|
|||||||
// remove this cast to a vec4.
|
// remove this cast to a vec4.
|
||||||
GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage);
|
GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage);
|
||||||
|
|
||||||
pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4);
|
pb->emitAndInstallProcs(optState, &inputColor, &inputCoverageVec4);
|
||||||
|
|
||||||
if (hasVertexShader) {
|
if (hasVertexShader) {
|
||||||
pb->fVS.transformToNormalizedDeviceSpace();
|
pb->fVS.transformSkiaToGLCoords();
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the secondary color output if necessary
|
// write the secondary color output if necessary
|
||||||
@ -173,17 +171,7 @@ GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32
|
|||||||
UniformInfo& uni = fUniforms.push_back();
|
UniformInfo& uni = fUniforms.push_back();
|
||||||
uni.fVariable.setType(type);
|
uni.fVariable.setType(type);
|
||||||
uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
|
uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
|
||||||
// TODO this is a bit hacky, lets think of a better way. Basically we need to be able to use
|
this->nameVariable(uni.fVariable.accessName(), 'u', name);
|
||||||
// the uniform view matrix name in the GP, and the GP is immutable so it has to tell the PB
|
|
||||||
// exactly what name it wants to use for the uniform view matrix. If we prefix anythings, then
|
|
||||||
// the names will mismatch. I think the correct solution is to have all GPs which need the
|
|
||||||
// uniform view matrix, they should upload the view matrix in their setData along with regular
|
|
||||||
// uniforms.
|
|
||||||
char prefix = 'u';
|
|
||||||
if ('u' == name[0]) {
|
|
||||||
prefix = '\0';
|
|
||||||
}
|
|
||||||
this->nameVariable(uni.fVariable.accessName(), prefix, name);
|
|
||||||
uni.fVariable.setArrayCount(count);
|
uni.fVariable.setArrayCount(count);
|
||||||
uni.fVisibility = visibility;
|
uni.fVisibility = visibility;
|
||||||
|
|
||||||
@ -242,40 +230,23 @@ void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor,
|
void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState,
|
||||||
|
GrGLSLExpr4* inputColor,
|
||||||
GrGLSLExpr4* inputCoverage) {
|
GrGLSLExpr4* inputCoverage) {
|
||||||
// We need to collect all of the transforms to thread them through the GP in the case of GPs
|
|
||||||
// which use additional shader stages between the VS and the FS. To do this we emit a dummy
|
|
||||||
// input coverage
|
|
||||||
GrGLSLExpr4 coverageInput = *inputCoverage;
|
|
||||||
if (fOptState.hasGeometryProcessor()) {
|
|
||||||
AutoStageAdvance adv(this);
|
|
||||||
SkString outColorName;
|
|
||||||
this->nameVariable(&outColorName, '\0', "gpOutput");
|
|
||||||
coverageInput = outColorName;
|
|
||||||
}
|
|
||||||
GrGLSLExpr4 gpOutput = coverageInput;
|
|
||||||
|
|
||||||
// Emit fragment processors
|
|
||||||
fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
|
fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
|
||||||
int numProcs = fOptState.numFragmentStages();
|
int numProcs = optState.numFragmentStages();
|
||||||
this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor);
|
this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor);
|
||||||
this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, &coverageInput);
|
if (optState.hasGeometryProcessor()) {
|
||||||
|
const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
|
||||||
// We have to save the existing code stack, and then append it to the fragment shader code
|
|
||||||
// after emiting the GP
|
|
||||||
if (fOptState.hasGeometryProcessor()) {
|
|
||||||
SkString existingCode(fFS.fCode);
|
|
||||||
fFS.fCode.reset();
|
|
||||||
const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor();
|
|
||||||
fVS.emitAttributes(gp);
|
fVS.emitAttributes(gp);
|
||||||
ProcKeyProvider keyProvider(&fDesc,
|
ProcKeyProvider keyProvider(&fDesc,
|
||||||
ProcKeyProvider::kGeometry_ProcessorType,
|
ProcKeyProvider::kGeometry_ProcessorType,
|
||||||
GrGLProgramDescBuilder::kProcessorKeyOffsetsAndLengthOffset);
|
GrGLProgramDescBuilder::kProcessorKeyOffsetsAndLengthOffset);
|
||||||
this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &gpOutput);
|
GrGLSLExpr4 output;
|
||||||
fFS.fCode.append(existingCode);
|
this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &output);
|
||||||
|
*inputCoverage = output;
|
||||||
}
|
}
|
||||||
*inputCoverage = coverageInput;
|
this->emitAndInstallFragProcs(optState.numColorStages(), numProcs, inputCoverage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut) {
|
void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut) {
|
||||||
@ -301,14 +272,9 @@ void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
|
|||||||
// Program builders have a bit of state we need to clear with each effect
|
// Program builders have a bit of state we need to clear with each effect
|
||||||
AutoStageAdvance adv(this);
|
AutoStageAdvance adv(this);
|
||||||
|
|
||||||
// create var to hold stage result. If we already have a valid output name, just use that
|
// create var to hold stage result
|
||||||
// otherwise create a new mangled one.
|
|
||||||
SkString outColorName;
|
SkString outColorName;
|
||||||
if (output->isValid()) {
|
this->nameVariable(&outColorName, '\0', "output");
|
||||||
outColorName = output->c_str();
|
|
||||||
} else {
|
|
||||||
this->nameVariable(&outColorName, '\0', "output");
|
|
||||||
}
|
|
||||||
fFS.codeAppendf("vec4 %s;", outColorName.c_str());
|
fFS.codeAppendf("vec4 %s;", outColorName.c_str());
|
||||||
*output = outColorName;
|
*output = outColorName;
|
||||||
|
|
||||||
@ -349,8 +315,8 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentStage& fs,
|
|||||||
|
|
||||||
void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
|
void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
|
||||||
const GrProcessorKey& key,
|
const GrProcessorKey& key,
|
||||||
const char* outCoverage,
|
const char* outColor,
|
||||||
const char* inCoverage) {
|
const char* inColor) {
|
||||||
SkASSERT(!fGeometryProcessor);
|
SkASSERT(!fGeometryProcessor);
|
||||||
fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
|
fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
|
||||||
|
|
||||||
@ -359,7 +325,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
|
|||||||
SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
|
SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
|
||||||
this->emitSamplers(gp, &samplers, fGeometryProcessor);
|
this->emitSamplers(gp, &samplers, fGeometryProcessor);
|
||||||
|
|
||||||
GrGLGeometryProcessor::EmitArgs args(this, gp, key, outCoverage, inCoverage, samplers);
|
GrGLGeometryProcessor::EmitArgs args(this, gp, key, outColor, inColor, samplers);
|
||||||
fGeometryProcessor->fGLProc->emitCode(args);
|
fGeometryProcessor->fGLProc->emitCode(args);
|
||||||
|
|
||||||
// We have to check that effects and the code they emit are consistent, ie if an effect
|
// We have to check that effects and the code they emit are consistent, ie if an effect
|
||||||
@ -408,13 +374,23 @@ void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
|
|||||||
suffixedVaryingName.appendf("_%i", t);
|
suffixedVaryingName.appendf("_%i", t);
|
||||||
varyingName = suffixedVaryingName.c_str();
|
varyingName = suffixedVaryingName.c_str();
|
||||||
}
|
}
|
||||||
const char* coords = kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
|
|
||||||
fVS.positionAttribute().c_str() :
|
|
||||||
fVS.localCoordsAttribute().c_str();
|
|
||||||
GrGLVertToFrag v(varyingType);
|
GrGLVertToFrag v(varyingType);
|
||||||
this->addCoordVarying(varyingName, &v, uniName, coords);
|
this->addVarying(varyingName, &v);
|
||||||
|
|
||||||
|
const GrGLShaderVar& coords =
|
||||||
|
kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
|
||||||
|
fVS.positionAttribute() :
|
||||||
|
fVS.localCoordsAttribute();
|
||||||
|
|
||||||
|
// varying = matrix * coords (logically)
|
||||||
SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
|
SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
|
||||||
|
if (kVec2f_GrSLType == varyingType) {
|
||||||
|
fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
|
||||||
|
v.vsOut(), uniName, coords.c_str());
|
||||||
|
} else {
|
||||||
|
fVS.codeAppendf("%s = %s * vec3(%s, 1);",
|
||||||
|
v.vsOut(), uniName, coords.c_str());
|
||||||
|
}
|
||||||
SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
|
SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
|
||||||
(SkString(v.fsIn()), varyingType));
|
(SkString(v.fsIn()), varyingType));
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,8 @@ protected:
|
|||||||
// generating stage code.
|
// generating stage code.
|
||||||
void nameVariable(SkString* out, char prefix, const char* name);
|
void nameVariable(SkString* out, char prefix, const char* name);
|
||||||
void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr1* inputCoverage);
|
void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr1* inputCoverage);
|
||||||
void emitAndInstallProcs(GrGLSLExpr4* inputColor,
|
void emitAndInstallProcs(const GrOptDrawState& optState,
|
||||||
|
GrGLSLExpr4* inputColor,
|
||||||
GrGLSLExpr4* inputCoverage);
|
GrGLSLExpr4* inputCoverage);
|
||||||
void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
|
void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
|
||||||
template <class Proc>
|
template <class Proc>
|
||||||
@ -258,8 +259,8 @@ protected:
|
|||||||
const char* inColor);
|
const char* inColor);
|
||||||
void emitAndInstallProc(const GrGeometryProcessor&,
|
void emitAndInstallProc(const GrGeometryProcessor&,
|
||||||
const GrProcessorKey&,
|
const GrProcessorKey&,
|
||||||
const char* outCoverage,
|
const char* outColor,
|
||||||
const char* inCoverage);
|
const char* inColor);
|
||||||
void verify(const GrGeometryProcessor&);
|
void verify(const GrGeometryProcessor&);
|
||||||
void verify(const GrFragmentProcessor&);
|
void verify(const GrFragmentProcessor&);
|
||||||
void emitSamplers(const GrProcessor&,
|
void emitSamplers(const GrProcessor&,
|
||||||
@ -313,22 +314,6 @@ protected:
|
|||||||
void enterStage() { fOutOfStage = false; }
|
void enterStage() { fOutOfStage = false; }
|
||||||
int stageIndex() const { return fStageIndex; }
|
int stageIndex() const { return fStageIndex; }
|
||||||
|
|
||||||
struct TransformVarying {
|
|
||||||
TransformVarying(const GrGLVarying& v, const char* uniName, const char* sourceCoords)
|
|
||||||
: fV(v), fUniName(uniName), fSourceCoords(sourceCoords) {}
|
|
||||||
GrGLVarying fV;
|
|
||||||
SkString fUniName;
|
|
||||||
SkString fSourceCoords;
|
|
||||||
};
|
|
||||||
|
|
||||||
void addCoordVarying(const char* name, GrGLVarying* v, const char* uniName,
|
|
||||||
const char* sourceCoords) {
|
|
||||||
this->addVarying(name, v);
|
|
||||||
fCoordVaryings.push_back(TransformVarying(*v, uniName, sourceCoords));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* rtAdjustment() const { return "rtAdjustment"; }
|
|
||||||
|
|
||||||
// number of each input/output type in a single allocation block, used by many builders
|
// number of each input/output type in a single allocation block, used by many builders
|
||||||
static const int kVarsPerBlock;
|
static const int kVarsPerBlock;
|
||||||
|
|
||||||
@ -346,7 +331,6 @@ protected:
|
|||||||
const GrProgramDesc& fDesc;
|
const GrProgramDesc& fDesc;
|
||||||
GrGpuGL* fGpu;
|
GrGpuGL* fGpu;
|
||||||
UniformInfoArray fUniforms;
|
UniformInfoArray fUniforms;
|
||||||
SkSTArray<16, TransformVarying, true> fCoordVaryings;
|
|
||||||
|
|
||||||
friend class GrGLShaderBuilder;
|
friend class GrGLShaderBuilder;
|
||||||
friend class GrGLVertexBuilder;
|
friend class GrGLVertexBuilder;
|
||||||
|
@ -20,7 +20,6 @@ GrGLVertexBuilder::GrGLVertexBuilder(GrGLProgramBuilder* program)
|
|||||||
: INHERITED(program)
|
: INHERITED(program)
|
||||||
, fPositionVar(NULL)
|
, fPositionVar(NULL)
|
||||||
, fLocalCoordsVar(NULL)
|
, fLocalCoordsVar(NULL)
|
||||||
, fRtAdjustName(NULL)
|
|
||||||
, fEffectAttribOffset(0) {
|
, fEffectAttribOffset(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,22 +31,9 @@ void GrGLVertexBuilder::addVarying(const char* name, GrGLVarying* v) {
|
|||||||
v->fVsOut = fOutputs.back().getName().c_str();
|
v->fVsOut = fOutputs.back().getName().c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLVertexBuilder::setupUniformViewMatrix() {
|
void GrGLVertexBuilder::setupLocalCoords() {
|
||||||
fProgramBuilder->fUniformHandles.fViewMatrixUni =
|
|
||||||
fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
|
|
||||||
kMat33f_GrSLType,
|
|
||||||
this->uViewM());
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrGLVertexBuilder::setupPositionAndLocalCoords() {
|
|
||||||
// Setup position
|
|
||||||
this->codeAppendf("vec3 %s;", this->glPosition());
|
|
||||||
|
|
||||||
// setup position and local coords attribute
|
|
||||||
fPositionVar = &fInputs.push_back();
|
fPositionVar = &fInputs.push_back();
|
||||||
fPositionVar->set(kVec2f_GrSLType,
|
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "inPosition");
|
||||||
GrGLShaderVar::kAttribute_TypeModifier,
|
|
||||||
this->inPosition());
|
|
||||||
if (-1 != fProgramBuilder->header().fLocalCoordAttributeIndex) {
|
if (-1 != fProgramBuilder->header().fLocalCoordAttributeIndex) {
|
||||||
fLocalCoordsVar = &fInputs.push_back();
|
fLocalCoordsVar = &fInputs.push_back();
|
||||||
fLocalCoordsVar->set(kVec2f_GrSLType,
|
fLocalCoordsVar->set(kVec2f_GrSLType,
|
||||||
@ -59,6 +45,18 @@ void GrGLVertexBuilder::setupPositionAndLocalCoords() {
|
|||||||
fEffectAttribOffset = fInputs.count();
|
fEffectAttribOffset = fInputs.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GrGLVertexBuilder::transformGLToSkiaCoords() {
|
||||||
|
const char* viewMName;
|
||||||
|
fProgramBuilder->fUniformHandles.fViewMatrixUni =
|
||||||
|
fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
|
||||||
|
kMat33f_GrSLType,
|
||||||
|
"ViewM",
|
||||||
|
&viewMName);
|
||||||
|
|
||||||
|
// Transform the position into Skia's device coords.
|
||||||
|
this->codeAppendf("vec3 pos3 = %s * vec3(%s, 1);", viewMName, fPositionVar->c_str());
|
||||||
|
}
|
||||||
|
|
||||||
void GrGLVertexBuilder::setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out) {
|
void GrGLVertexBuilder::setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out) {
|
||||||
GrGLVertToFrag v(kFloat_GrSLType);
|
GrGLVertToFrag v(kFloat_GrSLType);
|
||||||
fProgramBuilder->addVarying(inName, &v);
|
fProgramBuilder->addVarying(inName, &v);
|
||||||
@ -93,34 +91,17 @@ void GrGLVertexBuilder::emitAttributes(const GrGeometryProcessor& gp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLVertexBuilder::transformToNormalizedDeviceSpace() {
|
void GrGLVertexBuilder::transformSkiaToGLCoords() {
|
||||||
// setup RT Uniform
|
const char* rtAdjustName;
|
||||||
fProgramBuilder->fUniformHandles.fRTAdjustmentUni =
|
fProgramBuilder->fUniformHandles.fRTAdjustmentUni =
|
||||||
fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
|
fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
|
||||||
kVec4f_GrSLType,
|
kVec4f_GrSLType,
|
||||||
fProgramBuilder->rtAdjustment(),
|
"rtAdjustment",
|
||||||
&fRtAdjustName);
|
&rtAdjustName);
|
||||||
// Wire transforms
|
|
||||||
SkTArray<GrGLProgramBuilder::TransformVarying, true>& transVs = fProgramBuilder->fCoordVaryings;
|
|
||||||
int transformCount = transVs.count();
|
|
||||||
for (int i = 0; i < transformCount; i++) {
|
|
||||||
const char* coords = transVs[i].fSourceCoords.c_str();
|
|
||||||
|
|
||||||
// varying = matrix * coords (logically)
|
|
||||||
const GrGLVarying& v = transVs[i].fV;
|
|
||||||
if (kVec2f_GrSLType == v.fType) {
|
|
||||||
this->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.fVsOut, transVs[i].fUniName.c_str(),
|
|
||||||
coords);
|
|
||||||
} else {
|
|
||||||
this->codeAppendf("%s = %s * vec3(%s, 1);", v.fVsOut, transVs[i].fUniName.c_str(),
|
|
||||||
coords);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform from Skia's device coords to GL's normalized device coords.
|
// Transform from Skia's device coords to GL's normalized device coords.
|
||||||
this->codeAppendf("gl_Position = vec4(dot(%s.xz, %s.xy), dot(%s.yz, %s.zw), 0, %s.z);",
|
this->codeAppendf("gl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);",
|
||||||
this->glPosition(), fRtAdjustName, this->glPosition(), fRtAdjustName,
|
rtAdjustName, rtAdjustName);
|
||||||
this->glPosition());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) {
|
void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) {
|
||||||
|
@ -31,15 +31,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
|
const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
|
||||||
|
|
||||||
/** returns the expected position output */
|
|
||||||
const char* glPosition() const { return "pos3"; }
|
|
||||||
|
|
||||||
/** returns the expected uviewM matrix */
|
|
||||||
// TODO all of this fixed function stuff can live on the GP/PP
|
|
||||||
const char* uViewM() const { return "uViewM"; }
|
|
||||||
const char* inPosition() const { return "inPosition"; }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
* Internal call for GrGLProgramBuilder.addVarying
|
* Internal call for GrGLProgramBuilder.addVarying
|
||||||
@ -49,13 +40,12 @@ private:
|
|||||||
/*
|
/*
|
||||||
* private helpers for compilation by GrGLProgramBuilder
|
* private helpers for compilation by GrGLProgramBuilder
|
||||||
*/
|
*/
|
||||||
void transformToNormalizedDeviceSpace();
|
void setupLocalCoords();
|
||||||
//TODO GP itself should setup the uniform view matrix
|
void transformGLToSkiaCoords();
|
||||||
void setupUniformViewMatrix();
|
|
||||||
void setupPositionAndLocalCoords();
|
|
||||||
void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out);
|
void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out);
|
||||||
void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr4* out);
|
void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr4* out);
|
||||||
void emitAttributes(const GrGeometryProcessor& gp);
|
void emitAttributes(const GrGeometryProcessor& gp);
|
||||||
|
void transformSkiaToGLCoords();
|
||||||
void bindVertexAttributes(GrGLuint programID);
|
void bindVertexAttributes(GrGLuint programID);
|
||||||
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
|
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
|
||||||
|
|
||||||
@ -71,7 +61,6 @@ private:
|
|||||||
|
|
||||||
GrGLShaderVar* fPositionVar;
|
GrGLShaderVar* fPositionVar;
|
||||||
GrGLShaderVar* fLocalCoordsVar;
|
GrGLShaderVar* fLocalCoordsVar;
|
||||||
const char* fRtAdjustName;
|
|
||||||
int fEffectAttribOffset;
|
int fEffectAttribOffset;
|
||||||
|
|
||||||
friend class GrGLProgramBuilder;
|
friend class GrGLProgramBuilder;
|
||||||
|
Loading…
Reference in New Issue
Block a user