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.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.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
|
||||
true when the two prcoessors are of the same subclass (i.e. they return the same object from
|
||||
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
|
||||
processors' keys computed by the GrBackendEffectFactory. */
|
||||
bool isEqual(const GrGeometryProcessor& that) const {
|
||||
|
@ -561,10 +561,6 @@ public:
|
||||
const GrShaderVar& inQuadEdge = args.fGP.cast<QuadEdgeEffect>().inQuadEdge();
|
||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
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*) {}
|
||||
|
@ -14,6 +14,251 @@
|
||||
#include "SkColorPriv.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 {
|
||||
@ -303,6 +548,155 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
|
||||
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,
|
||||
const SkRect& rect,
|
||||
const SkMatrix& combinedMatrix,
|
||||
|
@ -44,7 +44,17 @@ public:
|
||||
const SkRect& rect,
|
||||
const SkMatrix& combinedMatrix,
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
void strokeAARect(GrDrawTarget* target,
|
||||
@ -66,6 +76,14 @@ private:
|
||||
const SkMatrix& combinedMatrix,
|
||||
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,
|
||||
const SkRect& devOutside,
|
||||
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 "GrDefaultGeoProcFactory.h"
|
||||
#include "GrDrawState.h"
|
||||
#include "GrDrawTargetCaps.h"
|
||||
#include "GrGpu.h"
|
||||
#include "gl/GrGpuGL.h"
|
||||
|
||||
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
||||
BlendOptFlags blendOptFlags,
|
||||
@ -64,10 +63,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
||||
// Copy GeometryProcesssor from DS or ODS
|
||||
if (drawState.hasGeometryProcessor()) {
|
||||
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 {
|
||||
fGeometryProcessor.reset(NULL);
|
||||
}
|
||||
|
@ -100,10 +100,6 @@ public:
|
||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();;
|
||||
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();
|
||||
fsBuilder->codeAppendf("float d = length(%s.xy);", 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(),
|
||||
ellipseEffect.inEllipseRadii().c_str());
|
||||
|
||||
// setup position varying
|
||||
vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(),
|
||||
vsBuilder->uViewM(), vsBuilder->inPosition());
|
||||
|
||||
// for outer curve
|
||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
|
||||
@ -373,10 +365,6 @@ public:
|
||||
vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
|
||||
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();
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
|
@ -38,7 +38,7 @@ GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
|
||||
* manually adjusted.
|
||||
*/
|
||||
static const int kFPFactoryCount = 37;
|
||||
static const int kGPFactoryCount = 14;
|
||||
static const int kGPFactoryCount = 15;
|
||||
|
||||
template<>
|
||||
void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
|
||||
|
@ -44,10 +44,6 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
|
||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
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();
|
||||
fsBuilder->codeAppend("float edgeAlpha;");
|
||||
|
||||
@ -188,10 +184,6 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
|
||||
const GrShaderVar& inHairQuadEdge = args.fGP.cast<GrQuadEffect>().inHairQuadEdge();
|
||||
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();
|
||||
fsBuilder->codeAppendf("float edgeAlpha;");
|
||||
|
||||
@ -318,10 +310,6 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
|
||||
const GrShaderVar& inCubicCoeffs = args.fGP.cast<GrCubicEffect>().inCubicCoeffs();
|
||||
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();
|
||||
|
||||
GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
|
||||
|
@ -31,10 +31,6 @@ public:
|
||||
const GrShaderVar& inTextureCoords = customCoordsTextureEffect.inTextureCoords();
|
||||
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();
|
||||
fsBuilder->codeAppendf("%s = ", args.fOutput);
|
||||
fsBuilder->appendTextureLookupAndModulate(args.fInput,
|
||||
|
@ -520,10 +520,6 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) {
|
||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
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
|
||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
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();
|
||||
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
|
||||
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
|
||||
|
@ -45,10 +45,6 @@ public:
|
||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
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;
|
||||
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
||||
kVec2f_GrSLType, "TextureSize",
|
||||
@ -260,10 +256,6 @@ public:
|
||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
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;
|
||||
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
||||
kVec2f_GrSLType, "TextureSize",
|
||||
@ -418,10 +410,6 @@ public:
|
||||
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
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;
|
||||
// width, height, 1/(3*width)
|
||||
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
||||
|
@ -106,10 +106,6 @@ public:
|
||||
return fExpr.c_str();
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return kFullExpr_ExprType != fType || !fExpr.isEmpty();
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Constructs an invalid expression.
|
||||
* Useful only as a return value from functions that never actually return
|
||||
@ -170,6 +166,10 @@ protected:
|
||||
fExpr.appendf(format, in0, in1);
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return kFullExpr_ExprType != fType || !fExpr.isEmpty();
|
||||
}
|
||||
|
||||
/** Returns expression casted to another type.
|
||||
* Generic implementation that is called for non-trivial cases of casts. */
|
||||
template <typename T>
|
||||
|
@ -57,11 +57,9 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
|
||||
bool hasVertexShader = !(header.fUseNvpr &&
|
||||
gpu->glPathRendering()->texturingMode() ==
|
||||
GrGLPathRendering::FixedFunction_TexturingMode);
|
||||
|
||||
if (hasVertexShader) {
|
||||
pb->fVS.setupUniformViewMatrix();
|
||||
pb->fVS.setupPositionAndLocalCoords();
|
||||
|
||||
pb->fVS.setupLocalCoords();
|
||||
pb->fVS.transformGLToSkiaCoords();
|
||||
if (header.fEmitsPointSize) {
|
||||
pb->fVS.codeAppend("gl_PointSize = 1.0;");
|
||||
}
|
||||
@ -77,10 +75,10 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
|
||||
// remove this cast to a vec4.
|
||||
GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage);
|
||||
|
||||
pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4);
|
||||
pb->emitAndInstallProcs(optState, &inputColor, &inputCoverageVec4);
|
||||
|
||||
if (hasVertexShader) {
|
||||
pb->fVS.transformToNormalizedDeviceSpace();
|
||||
pb->fVS.transformSkiaToGLCoords();
|
||||
}
|
||||
|
||||
// write the secondary color output if necessary
|
||||
@ -173,17 +171,7 @@ GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32
|
||||
UniformInfo& uni = fUniforms.push_back();
|
||||
uni.fVariable.setType(type);
|
||||
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
|
||||
// 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);
|
||||
this->nameVariable(uni.fVariable.accessName(), 'u', name);
|
||||
uni.fVariable.setArrayCount(count);
|
||||
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) {
|
||||
// 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));
|
||||
int numProcs = fOptState.numFragmentStages();
|
||||
this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor);
|
||||
this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, &coverageInput);
|
||||
|
||||
// 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();
|
||||
int numProcs = optState.numFragmentStages();
|
||||
this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor);
|
||||
if (optState.hasGeometryProcessor()) {
|
||||
const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
|
||||
fVS.emitAttributes(gp);
|
||||
ProcKeyProvider keyProvider(&fDesc,
|
||||
ProcKeyProvider::kGeometry_ProcessorType,
|
||||
GrGLProgramDescBuilder::kProcessorKeyOffsetsAndLengthOffset);
|
||||
this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &gpOutput);
|
||||
fFS.fCode.append(existingCode);
|
||||
GrGLSLExpr4 output;
|
||||
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) {
|
||||
@ -301,14 +272,9 @@ void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
|
||||
// Program builders have a bit of state we need to clear with each effect
|
||||
AutoStageAdvance adv(this);
|
||||
|
||||
// create var to hold stage result. If we already have a valid output name, just use that
|
||||
// otherwise create a new mangled one.
|
||||
// create var to hold stage result
|
||||
SkString outColorName;
|
||||
if (output->isValid()) {
|
||||
outColorName = output->c_str();
|
||||
} else {
|
||||
this->nameVariable(&outColorName, '\0', "output");
|
||||
}
|
||||
fFS.codeAppendf("vec4 %s;", outColorName.c_str());
|
||||
*output = outColorName;
|
||||
|
||||
@ -349,8 +315,8 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentStage& fs,
|
||||
|
||||
void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
|
||||
const GrProcessorKey& key,
|
||||
const char* outCoverage,
|
||||
const char* inCoverage) {
|
||||
const char* outColor,
|
||||
const char* inColor) {
|
||||
SkASSERT(!fGeometryProcessor);
|
||||
fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
|
||||
|
||||
@ -359,7 +325,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
|
||||
SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
|
||||
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);
|
||||
|
||||
// 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);
|
||||
varyingName = suffixedVaryingName.c_str();
|
||||
}
|
||||
const char* coords = kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
|
||||
fVS.positionAttribute().c_str() :
|
||||
fVS.localCoordsAttribute().c_str();
|
||||
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);
|
||||
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,
|
||||
(SkString(v.fsIn()), varyingType));
|
||||
}
|
||||
|
@ -241,7 +241,8 @@ protected:
|
||||
// generating stage code.
|
||||
void nameVariable(SkString* out, char prefix, const char* name);
|
||||
void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr1* inputCoverage);
|
||||
void emitAndInstallProcs(GrGLSLExpr4* inputColor,
|
||||
void emitAndInstallProcs(const GrOptDrawState& optState,
|
||||
GrGLSLExpr4* inputColor,
|
||||
GrGLSLExpr4* inputCoverage);
|
||||
void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
|
||||
template <class Proc>
|
||||
@ -258,8 +259,8 @@ protected:
|
||||
const char* inColor);
|
||||
void emitAndInstallProc(const GrGeometryProcessor&,
|
||||
const GrProcessorKey&,
|
||||
const char* outCoverage,
|
||||
const char* inCoverage);
|
||||
const char* outColor,
|
||||
const char* inColor);
|
||||
void verify(const GrGeometryProcessor&);
|
||||
void verify(const GrFragmentProcessor&);
|
||||
void emitSamplers(const GrProcessor&,
|
||||
@ -313,22 +314,6 @@ protected:
|
||||
void enterStage() { fOutOfStage = false; }
|
||||
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
|
||||
static const int kVarsPerBlock;
|
||||
|
||||
@ -346,7 +331,6 @@ protected:
|
||||
const GrProgramDesc& fDesc;
|
||||
GrGpuGL* fGpu;
|
||||
UniformInfoArray fUniforms;
|
||||
SkSTArray<16, TransformVarying, true> fCoordVaryings;
|
||||
|
||||
friend class GrGLShaderBuilder;
|
||||
friend class GrGLVertexBuilder;
|
||||
|
@ -20,7 +20,6 @@ GrGLVertexBuilder::GrGLVertexBuilder(GrGLProgramBuilder* program)
|
||||
: INHERITED(program)
|
||||
, fPositionVar(NULL)
|
||||
, fLocalCoordsVar(NULL)
|
||||
, fRtAdjustName(NULL)
|
||||
, fEffectAttribOffset(0) {
|
||||
}
|
||||
|
||||
@ -32,22 +31,9 @@ void GrGLVertexBuilder::addVarying(const char* name, GrGLVarying* v) {
|
||||
v->fVsOut = fOutputs.back().getName().c_str();
|
||||
}
|
||||
|
||||
void GrGLVertexBuilder::setupUniformViewMatrix() {
|
||||
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
|
||||
void GrGLVertexBuilder::setupLocalCoords() {
|
||||
fPositionVar = &fInputs.push_back();
|
||||
fPositionVar->set(kVec2f_GrSLType,
|
||||
GrGLShaderVar::kAttribute_TypeModifier,
|
||||
this->inPosition());
|
||||
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "inPosition");
|
||||
if (-1 != fProgramBuilder->header().fLocalCoordAttributeIndex) {
|
||||
fLocalCoordsVar = &fInputs.push_back();
|
||||
fLocalCoordsVar->set(kVec2f_GrSLType,
|
||||
@ -59,6 +45,18 @@ void GrGLVertexBuilder::setupPositionAndLocalCoords() {
|
||||
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) {
|
||||
GrGLVertToFrag v(kFloat_GrSLType);
|
||||
fProgramBuilder->addVarying(inName, &v);
|
||||
@ -93,34 +91,17 @@ void GrGLVertexBuilder::emitAttributes(const GrGeometryProcessor& gp) {
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLVertexBuilder::transformToNormalizedDeviceSpace() {
|
||||
// setup RT Uniform
|
||||
void GrGLVertexBuilder::transformSkiaToGLCoords() {
|
||||
const char* rtAdjustName;
|
||||
fProgramBuilder->fUniformHandles.fRTAdjustmentUni =
|
||||
fProgramBuilder->addUniform(GrGLProgramBuilder::kVertex_Visibility,
|
||||
kVec4f_GrSLType,
|
||||
fProgramBuilder->rtAdjustment(),
|
||||
&fRtAdjustName);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
"rtAdjustment",
|
||||
&rtAdjustName);
|
||||
|
||||
// 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->glPosition(), fRtAdjustName, this->glPosition(), fRtAdjustName,
|
||||
this->glPosition());
|
||||
this->codeAppendf("gl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);",
|
||||
rtAdjustName, rtAdjustName);
|
||||
}
|
||||
|
||||
void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) {
|
||||
|
@ -31,15 +31,6 @@ public:
|
||||
*/
|
||||
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:
|
||||
/*
|
||||
* Internal call for GrGLProgramBuilder.addVarying
|
||||
@ -49,13 +40,12 @@ private:
|
||||
/*
|
||||
* private helpers for compilation by GrGLProgramBuilder
|
||||
*/
|
||||
void transformToNormalizedDeviceSpace();
|
||||
//TODO GP itself should setup the uniform view matrix
|
||||
void setupUniformViewMatrix();
|
||||
void setupPositionAndLocalCoords();
|
||||
void setupLocalCoords();
|
||||
void transformGLToSkiaCoords();
|
||||
void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr1* out);
|
||||
void setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr4* out);
|
||||
void emitAttributes(const GrGeometryProcessor& gp);
|
||||
void transformSkiaToGLCoords();
|
||||
void bindVertexAttributes(GrGLuint programID);
|
||||
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
|
||||
|
||||
@ -71,7 +61,6 @@ private:
|
||||
|
||||
GrGLShaderVar* fPositionVar;
|
||||
GrGLShaderVar* fLocalCoordsVar;
|
||||
const char* fRtAdjustName;
|
||||
int fEffectAttribOffset;
|
||||
|
||||
friend class GrGLProgramBuilder;
|
||||
|
Loading…
Reference in New Issue
Block a user