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:
joshualitt 2014-11-07 12:08:03 -08:00 committed by Commit bot
parent ff343074b2
commit ee0ea3f0dd
19 changed files with 480 additions and 462 deletions

View File

@ -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',

View File

@ -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 {

View File

@ -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*) {}

View File

@ -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(&center, 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,

View File

@ -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,

View File

@ -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();
}

View File

@ -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

View File

@ -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);
} }

View File

@ -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));

View File

@ -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() {

View File

@ -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);

View File

@ -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,

View File

@ -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",

View File

@ -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,

View File

@ -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>

View File

@ -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()) {
outColorName = output->c_str();
} else {
this->nameVariable(&outColorName, '\0', "output"); 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));
} }

View File

@ -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;

View File

@ -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) {

View File

@ -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;