aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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());
}
}
}