Cleanup GrDefaultGeoProcFactory localCoords

TBR=bsalomon@google.com
BUG=skia:

Review URL: https://codereview.chromium.org/1257193002
This commit is contained in:
joshualitt 2015-07-28 10:01:18 -07:00 committed by Commit bot
parent b542bae1f5
commit 0d986d877e
3 changed files with 82 additions and 69 deletions

View File

@ -278,24 +278,43 @@ const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(uint32_t gpTypeFlags,
const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(const Color& color,
const Coverage& coverage,
LocalCoords::Type localCoords,
const SkMatrix& viewMatrix,
const SkMatrix& localMatrix) {
const LocalCoords& localCoords,
const SkMatrix& viewMatrix) {
uint32_t flags = 0;
flags |= color.fType == Color::kAttribute_Type ? kColor_GPType : 0;
flags |= coverage.fType == Coverage::kAttribute_Type ? kCoverage_GPType : 0;
flags |= localCoords == LocalCoords::kHasExplicit_Type ? kLocalCoord_GPType : 0;
flags |= localCoords.fType == LocalCoords::kHasExplicit_Type ? kLocalCoord_GPType : 0;
uint8_t inCoverage = coverage.fCoverage;
bool coverageWillBeIgnored = coverage.fType == Coverage::kNone_Type;
bool localCoordsWillBeRead = localCoords != LocalCoords::kNone_Type;
bool localCoordsWillBeRead = localCoords.fType != LocalCoords::kUnused_Type;
GrColor inColor = color.fColor;
return DefaultGeoProc::Create(flags,
inColor,
viewMatrix,
localMatrix,
localCoords.fMatrix ? *localCoords.fMatrix : SkMatrix::I(),
localCoordsWillBeRead,
coverageWillBeIgnored,
inCoverage);
}
const GrGeometryProcessor* GrDefaultGeoProcFactory::CreateForDeviceSpace(
const Color& color,
const Coverage& coverage,
const LocalCoords& localCoords,
const SkMatrix& viewMatrix) {
SkASSERT(LocalCoords::kUsePosition_Type == localCoords.fType);
SkMatrix invert = SkMatrix::I();
if (!viewMatrix.isIdentity() && !viewMatrix.invert(&invert)) {
SkDebugf("Could not invert\n");
return NULL;
}
if (localCoords.hasLocalMatrix()) {
invert.preConcat(*localCoords.fMatrix);
}
LocalCoords inverted(LocalCoords::kUsePosition_Type, &invert);
return Create(color, coverage, inverted);
}

View File

@ -111,26 +111,36 @@ public:
struct LocalCoords {
enum Type {
kNone_Type,
kUnused_Type,
kUsePosition_Type,
kHasExplicit_Type,
};
LocalCoords(Type type) : fType(type), fMatrix(NULL) {}
LocalCoords(Type type, const SkMatrix* matrix) : fType(type), fMatrix(matrix) {
SkASSERT(kUnused_Type != type);
}
bool hasLocalMatrix() const { return NULL != fMatrix; }
Type fType;
const SkMatrix* fMatrix;
};
static const GrGeometryProcessor* Create(const Color&,
const Coverage&,
LocalCoords::Type,
const SkMatrix& viewMatrix = SkMatrix::I(),
const SkMatrix& localMatrix = SkMatrix::I());
const LocalCoords&,
const SkMatrix& viewMatrix = SkMatrix::I());
/*
* The following functions are used to create default GPs. If you just need to create
* attributes separately from creating the default GP, use the SetAttribs function followed
* by the Create function. Otherwise use CreateAndSetAttribs to do both at once.
*
* You must unref the return from Create.
* Use this factory to create a GrGeometryProcessor that expects a device space vertex position
* attribute. The view matrix must still be provided to compute correctly transformed
* coordinates for GrFragmentProcessors. It may fail if the view matrix is not invertible.
*/
// TODO clean this up
static const GrGeometryProcessor* CreateForDeviceSpace(const Color&,
const Coverage&,
const LocalCoords&,
const SkMatrix& viewMatrix);
// TODO deprecate this
static const GrGeometryProcessor* Create(uint32_t gpTypeFlags,
GrColor,
bool localCoordsWillBeRead,

View File

@ -13,39 +13,6 @@
#include "GrDefaultGeoProcFactory.h"
#include "GrPrimitiveProcessor.h"
/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
have explicit local coords and sometimes not. We *could* always provide explicit local coords
and just duplicate the positions when the caller hasn't provided a local coord rect, but we
haven't seen a use case which frequently switches between local rect and no local rect draws.
The color param is used to determine whether the opaque hint can be set on the draw state.
The caller must populate the vertex colors itself.
The vertex attrib order is always pos, color, [local coords].
*/
static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords,
const SkMatrix* localMatrix,
bool coverageIgnored) {
typedef GrDefaultGeoProcFactory::Color Color;
typedef GrDefaultGeoProcFactory::Coverage Coverage;
typedef GrDefaultGeoProcFactory::LocalCoords LocalCoords;
Color color(Color::kAttribute_Type);
Coverage coverage(coverageIgnored ? Coverage::kNone_Type : Coverage::kSolid_Type);
LocalCoords::Type localCoords;
if (hasExplicitLocalCoords) {
localCoords = LocalCoords::kHasExplicit_Type;
} else {
localCoords = LocalCoords::kUsePosition_Type;
}
if (localMatrix) {
return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I(),
*localMatrix);
} else {
return GrDefaultGeoProcFactory::Create(color, coverage, localCoords);
}
}
class RectBatch : public GrBatch {
public:
struct Geometry {
@ -88,32 +55,17 @@ public:
}
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
// Go to device coords to allow batching across matrix changes
SkMatrix invert = SkMatrix::I();
// if we have a local rect, then we apply the localMatrix directly to the localRect to
// generate vertex local coords
bool hasExplicitLocalCoords = this->hasLocalRect();
if (!hasExplicitLocalCoords) {
if (!this->viewMatrix().isIdentity() && !this->viewMatrix().invert(&invert)) {
SkDebugf("Could not invert\n");
return;
}
if (this->hasLocalMatrix()) {
invert.preConcat(this->localMatrix());
}
SkAutoTUnref<const GrGeometryProcessor> gp(this->createRectGP());
if (!gp) {
SkDebugf("Could not create GrGeometryProcessor\n");
return;
}
SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLocalCoords,
&invert,
this->coverageIgnored()));
batchTarget->initDraw(gp, pipeline);
int instanceCount = fGeoData.count();
size_t vertexStride = gp->getVertexStride();
SkASSERT(hasExplicitLocalCoords ?
SkASSERT(this->hasLocalRect() ?
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
QuadHelper helper;
@ -211,6 +163,38 @@ private:
return true;
}
/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes
we have explicit local coords and sometimes not. We *could* always provide explicit local
coords and just duplicate the positions when the caller hasn't provided a local coord rect,
but we haven't seen a use case which frequently switches between local rect and no local
rect draws.
The color param is used to determine whether the opaque hint can be set on the draw state.
The caller must populate the vertex colors itself.
The vertex attrib order is always pos, color, [local coords].
*/
const GrGeometryProcessor* createRectGP() {
typedef GrDefaultGeoProcFactory::Color Color;
typedef GrDefaultGeoProcFactory::Coverage Coverage;
typedef GrDefaultGeoProcFactory::LocalCoords LocalCoords;
Color color(Color::kAttribute_Type);
Coverage coverage(this->coverageIgnored() ? Coverage::kNone_Type : Coverage::kSolid_Type);
// if we have a local rect, then we apply the localMatrix directly to the localRect to
// generate vertex local coords
if (this->hasLocalRect()) {
LocalCoords localCoords(LocalCoords::kHasExplicit_Type);
return GrDefaultGeoProcFactory::Create(color, coverage, localCoords);
} else {
LocalCoords localCoords(LocalCoords::kUsePosition_Type,
this->hasLocalMatrix() ? &this->localMatrix() : NULL);
return GrDefaultGeoProcFactory::CreateForDeviceSpace(color, coverage, localCoords,
this->viewMatrix());
}
}
struct BatchTracker {
GrColor fColor;
bool fUsesLocalCoords;