aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2018-05-22 14:14:07 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-22 18:32:45 +0000
commit17031a72532087c367e2ffab72c6d4391b168254 (patch)
tree683d634dd71efac2b48b7a9a71757a023c54c397
parent339133f82c30cd3080672db28e6f72c894cba05a (diff)
Use layered templates for optional vertex attributes in GrTextureOp.
Also, use templated member function rather than macro to generate vertices. Use enum class instead of bool for multitexturing template param. Change-Id: I2ef26c1e0db91b39cfde2e9661f3483988831469 Reviewed-on: https://skia-review.googlesource.com/129600 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
-rw-r--r--src/gpu/ops/GrTextureOp.cpp101
1 files changed, 59 insertions, 42 deletions
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index d2f775b05f..a2cd4eb79f 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -31,6 +31,8 @@
namespace {
+enum class MultiTexture : bool { kNo = false, kYes = true };
+
/**
* Geometry Processor that draws a texture modulated by a vertex color (though, this is meant to be
* the same value across all vertices of a quad and uses flat interpolation when available). This is
@@ -38,27 +40,38 @@ namespace {
*/
class TextureGeometryProcessor : public GrGeometryProcessor {
public:
- template <typename P> struct Vertex {
- static constexpr GrAA kAA = GrAA::kNo;
- static constexpr bool kIsMultiTexture = false;
- using Position = P;
- P fPosition;
- SkPoint fTextureCoords;
+ template <typename Pos> struct VertexCommon {
+ using Position = Pos;
+ Position fPosition;
GrColor fColor;
+ SkPoint fTextureCoords;
};
- template <typename P> struct AAVertex : Vertex<P> {
- static constexpr GrAA kAA = GrAA::kYes;
- SkPoint3 fEdges[4];
+
+ template <typename Pos, MultiTexture MT> struct OptionalMultiTextureVertex;
+ template <typename Pos>
+ struct OptionalMultiTextureVertex<Pos, MultiTexture::kNo> : VertexCommon<Pos> {
+ static constexpr MultiTexture kMultiTexture = MultiTexture::kNo;
};
- template <typename P> struct MultiTextureVertex : Vertex<P> {
- static constexpr bool kIsMultiTexture = true;
+ template <typename Pos>
+ struct OptionalMultiTextureVertex<Pos, MultiTexture::kYes> : VertexCommon<Pos> {
+ static constexpr MultiTexture kMultiTexture = MultiTexture::kYes;
int fTextureIdx;
};
- template <typename P> struct AAMultiTextureVertex : MultiTextureVertex<P> {
+
+ template <typename Pos, MultiTexture MT, GrAA> struct OptionalAAVertex;
+ template <typename Pos, MultiTexture MT>
+ struct OptionalAAVertex<Pos, MT, GrAA::kNo> : OptionalMultiTextureVertex<Pos, MT> {
+ static constexpr GrAA kAA = GrAA::kNo;
+ };
+ template <typename Pos, MultiTexture MT>
+ struct OptionalAAVertex<Pos, MT, GrAA::kYes> : OptionalMultiTextureVertex<Pos, MT> {
static constexpr GrAA kAA = GrAA::kYes;
SkPoint3 fEdges[4];
};
+ template <typename Pos, MultiTexture MT, GrAA AA>
+ using Vertex = OptionalAAVertex<Pos, MT, AA>;
+
// Maximum number of textures supported by this op. Must also be checked against the caps
// limit. These numbers were based on some limited experiments on a HP Z840 and Pixel XL 2016
// and could probably use more tuning.
@@ -279,8 +292,8 @@ private:
} else {
fPositions = this->addVertexAttrib("position", kFloat2_GrVertexAttribType);
}
- fTextureCoords = this->addVertexAttrib("textureCoords", kFloat2_GrVertexAttribType);
fColors = this->addVertexAttrib("color", kUByte4_norm_GrVertexAttribType);
+ fTextureCoords = this->addVertexAttrib("textureCoords", kFloat2_GrVertexAttribType);
if (samplerCnt > 1) {
// Here we initialize any extra samplers by repeating the last one samplerCnt - proxyCnt
@@ -483,9 +496,9 @@ private:
}
};
-template <typename V, bool MT = V::kIsMultiTexture> struct TexIdAssigner;
+template <typename V, MultiTexture MT = V::kMultiTexture> struct TexIdAssigner;
-template <typename V> struct TexIdAssigner<V, true> {
+template <typename V> struct TexIdAssigner<V, MultiTexture::kYes> {
static void Assign(V* vertices, int textureIdx) {
for (int i = 0; i < 4; ++i) {
vertices[i].fTextureIdx = textureIdx;
@@ -493,7 +506,7 @@ template <typename V> struct TexIdAssigner<V, true> {
}
};
-template <typename V> struct TexIdAssigner<V, false> {
+template <typename V> struct TexIdAssigner<V, MultiTexture::kNo> {
static void Assign(V* vertices, int textureIdx) {}
};
} // anonymous namespace
@@ -519,6 +532,7 @@ static void tessellate_quad(const GrPerspQuad& devQuad, const SkRect& srcRect, G
vertices[3].fColor = color;
TexIdAssigner<V>::Assign(vertices, textureIdx);
}
+
/**
* Op that implements GrTextureOp::Make. It draws textured quads. Each quad can modulate against a
* the texture by color. The blend with the destination is always src-over. The edges are non-AA.
@@ -638,6 +652,20 @@ __attribute__((no_sanitize("float-cast-overflow")))
fMaxApproxDstPixelArea = RectSizeAsSizeT(bounds);
}
+ template <typename Pos, MultiTexture MT, GrAA AA>
+ void tess(void* v, const float iw[], const float ih[], const GrGeometryProcessor* gp) {
+ using Vertex = TextureGeometryProcessor::Vertex<Pos, MT, AA>;
+ SkASSERT(gp->getVertexStride() == sizeof(Vertex));
+ auto vertices = static_cast<Vertex*>(v);
+ auto proxies = this->proxies();
+ for (const auto& draw : fDraws) {
+ auto origin = proxies[draw.fTextureIdx]->origin();
+ tessellate_quad<Vertex>(draw.fQuad, draw.fSrcRect, draw.fColor, origin, vertices,
+ iw[draw.fTextureIdx], ih[draw.fTextureIdx], draw.fTextureIdx);
+ vertices += 4;
+ }
+ }
+
void onPrepareDraws(Target* target) override {
sk_sp<GrTextureProxy> proxiesSPs[kMaxTextures];
auto proxies = this->proxies();
@@ -676,17 +704,6 @@ __attribute__((no_sanitize("float-cast-overflow")))
return;
}
-// Generic lambda in C++14?
-#define TESS_VERTS(Vertex) \
- SkASSERT(gp->getVertexStride() == sizeof(Vertex)); \
- auto vertices = static_cast<Vertex*>(vdata); \
- for (const auto& draw : fDraws) { \
- auto origin = proxies[draw.fTextureIdx]->origin(); \
- tessellate_quad<Vertex>(draw.fQuad, draw.fSrcRect, draw.fColor, origin, vertices, \
- iw[draw.fTextureIdx], ih[draw.fTextureIdx], draw.fTextureIdx); \
- vertices += 4; \
- }
-
float iw[kMaxTextures];
float ih[kMaxTextures];
for (int t = 0; t < fProxyCnt; ++t) {
@@ -695,32 +712,32 @@ __attribute__((no_sanitize("float-cast-overflow")))
ih[t] = 1.f / texture->height();
}
- if (1 == fProxyCnt) {
- if (coverageAA) {
- if (fPerspective) {
- TESS_VERTS(TextureGeometryProcessor::AAVertex<SkPoint3>)
+ if (fPerspective) {
+ if (fProxyCnt > 1) {
+ if (coverageAA) {
+ this->tess<SkPoint3, MultiTexture::kYes, GrAA::kYes>(vdata, iw, ih, gp.get());
} else {
- TESS_VERTS(TextureGeometryProcessor::AAVertex<SkPoint>)
+ this->tess<SkPoint3, MultiTexture::kYes, GrAA::kNo>(vdata, iw, ih, gp.get());
}
} else {
- if (fPerspective) {
- TESS_VERTS(TextureGeometryProcessor::Vertex<SkPoint3>)
+ if (coverageAA) {
+ this->tess<SkPoint3, MultiTexture::kNo, GrAA::kYes>(vdata, iw, ih, gp.get());
} else {
- TESS_VERTS(TextureGeometryProcessor::Vertex<SkPoint>)
+ this->tess<SkPoint3, MultiTexture::kNo, GrAA::kNo>(vdata, iw, ih, gp.get());
}
}
} else {
- if (coverageAA) {
- if (fPerspective) {
- TESS_VERTS(TextureGeometryProcessor::AAMultiTextureVertex<SkPoint3>)
+ if (fProxyCnt > 1) {
+ if (coverageAA) {
+ this->tess<SkPoint, MultiTexture::kYes, GrAA::kYes>(vdata, iw, ih, gp.get());
} else {
- TESS_VERTS(TextureGeometryProcessor::AAMultiTextureVertex<SkPoint>)
+ this->tess<SkPoint, MultiTexture::kYes, GrAA::kNo>(vdata, iw, ih, gp.get());
}
} else {
- if (fPerspective) {
- TESS_VERTS(TextureGeometryProcessor::MultiTextureVertex<SkPoint3>)
+ if (coverageAA) {
+ this->tess<SkPoint, MultiTexture::kNo, GrAA::kYes>(vdata, iw, ih, gp.get());
} else {
- TESS_VERTS(TextureGeometryProcessor::MultiTextureVertex<SkPoint>)
+ this->tess<SkPoint, MultiTexture::kNo, GrAA::kNo>(vdata, iw, ih, gp.get());
}
}
}