Reland "Track quad type on GrQuad directly"
This reverts commit 0dee19bacc00f327dca20cc7e4c0a97bc8082c0e.
Reason for revert: properly remember src quad type
Original change's description:
> Revert "Track quad type on GrQuad directly"
>
> This reverts commit 85766c4cd367596268588f53631a1c43376c929d.
>
> Reason for revert: red - so much red
>
> Original change's description:
> > Track quad type on GrQuad directly
> >
> > This makes subsequent higher-level drawing APIs more compact, and
> > shouldn't come with a performance hit. Everywhere we used to need
> > a GrPerspQuad, we'd also take the GrQuadType as a second argument.
> > The quad list types already deconstruct the quad so there's no
> > extra overhead in the op's memory usage.
> >
> > It also improves usability and decreases the likelihood that an
> > incorrect quad type is ever associated with the quad.
> >
> > Bug: skia:
> > Change-Id: Iba908fb133ad664744a5788a7088d90de0d3a1c2
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/214820
> > Reviewed-by: Brian Salomon <bsalomon@google.com>
> > Commit-Queue: Michael Ludwig <michaelludwig@google.com>
>
> TBR=bsalomon@google.com,robertphillips@google.com,michaelludwig@google.com
>
> Change-Id: Ied594673116fb901287b334fea41da3c71494fb1
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/215607
> Reviewed-by: Robert Phillips <robertphillips@google.com>
> Commit-Queue: Robert Phillips <robertphillips@google.com>
TBR=bsalomon@google.com,robertphillips@google.com,michaelludwig@google.com
Change-Id: Id5fb51218f2ace37086112caa2e43461d2f2b46b
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/215640
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/GrQuad.cpp b/src/gpu/GrQuad.cpp
index 379d1f6..bd01a68 100644
--- a/src/gpu/GrQuad.cpp
+++ b/src/gpu/GrQuad.cpp
@@ -69,10 +69,39 @@
*ys = V4f{skQuadPts[0].fY, skQuadPts[3].fY, skQuadPts[1].fY, skQuadPts[2].fY};
}
+// If an SkRect is transformed by this matrix, what class of quad is required to represent it.
+static GrQuadType quad_type_for_transformed_rect(const SkMatrix& matrix) {
+ if (matrix.rectStaysRect()) {
+ return GrQuadType::kRect;
+ } else if (matrix.preservesRightAngles()) {
+ return GrQuadType::kRectilinear;
+ } else if (matrix.hasPerspective()) {
+ return GrQuadType::kPerspective;
+ } else {
+ return GrQuadType::kStandard;
+ }
+}
+
+// Perform minimal analysis of 'pts' (which are suitable for MakeFromSkQuad), and determine a
+// quad type that will be as minimally general as possible.
+static GrQuadType quad_type_for_points(const SkPoint pts[4], const SkMatrix& matrix) {
+ if (matrix.hasPerspective()) {
+ return GrQuadType::kPerspective;
+ }
+ // If 'pts' was formed by SkRect::toQuad() and not transformed further, it is safe to use the
+ // quad type derived from 'matrix'. Otherwise don't waste any more time and assume kStandard
+ // (most general 2D quad).
+ if ((pts[0].fX == pts[3].fX && pts[1].fX == pts[2].fX) &&
+ (pts[0].fY == pts[1].fY && pts[2].fY == pts[3].fY)) {
+ return quad_type_for_transformed_rect(matrix);
+ } else {
+ return GrQuadType::kStandard;
+ }
+}
+
template <typename Q>
void GrResolveAATypeForQuad(GrAAType requestedAAType, GrQuadAAFlags requestedEdgeFlags,
- const Q& quad, GrQuadType knownType,
- GrAAType* outAAType, GrQuadAAFlags* outEdgeFlags) {
+ const Q& quad, GrAAType* outAAType, GrQuadAAFlags* outEdgeFlags) {
// Most cases will keep the requested types unchanged
*outAAType = requestedAAType;
*outEdgeFlags = requestedEdgeFlags;
@@ -86,7 +115,7 @@
} else {
// For coverage AA, if the quad is a rect and it lines up with pixel boundaries
// then overall aa and per-edge aa can be completely disabled
- if (knownType == GrQuadType::kRect && !quad.aaHasEffectOnRect()) {
+ if (quad.quadType() == GrQuadType::kRect && !quad.aaHasEffectOnRect()) {
*outAAType = GrAAType::kNone;
*outEdgeFlags = GrQuadAAFlags::kNone;
}
@@ -107,58 +136,46 @@
};
// Instantiate GrResolve... for GrQuad and GrPerspQuad
-template void GrResolveAATypeForQuad(GrAAType, GrQuadAAFlags, const GrQuad&, GrQuadType,
+template void GrResolveAATypeForQuad(GrAAType, GrQuadAAFlags, const GrQuad&,
GrAAType*, GrQuadAAFlags*);
-template void GrResolveAATypeForQuad(GrAAType, GrQuadAAFlags, const GrPerspQuad&, GrQuadType,
+template void GrResolveAATypeForQuad(GrAAType, GrQuadAAFlags, const GrPerspQuad&,
GrAAType*, GrQuadAAFlags*);
-GrQuadType GrQuadTypeForTransformedRect(const SkMatrix& matrix) {
- if (matrix.rectStaysRect()) {
- return GrQuadType::kRect;
- } else if (matrix.preservesRightAngles()) {
- return GrQuadType::kRectilinear;
- } else if (matrix.hasPerspective()) {
- return GrQuadType::kPerspective;
- } else {
- return GrQuadType::kStandard;
- }
-}
-
-GrQuadType GrQuadTypeForPoints(const SkPoint pts[4], const SkMatrix& matrix) {
- if (matrix.hasPerspective()) {
- return GrQuadType::kPerspective;
- }
- // If 'pts' was formed by SkRect::toQuad() and not transformed further, it is safe to use the
- // quad type derived from 'matrix'. Otherwise don't waste any more time and assume kStandard
- // (most general 2D quad).
- if ((pts[0].fX == pts[3].fX && pts[1].fX == pts[2].fX) &&
- (pts[0].fY == pts[1].fY && pts[2].fY == pts[3].fY)) {
- return GrQuadTypeForTransformedRect(matrix);
- } else {
- return GrQuadType::kStandard;
- }
-}
-
GrQuad GrQuad::MakeFromRect(const SkRect& rect, const SkMatrix& m) {
V4f x, y;
SkMatrix::TypeMask tm = m.getType();
+ GrQuadType type;
if (tm <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) {
map_rect_translate_scale(rect, m, &x, &y);
+ type = GrQuadType::kRect;
} else {
map_rect_general(rect, m, &x, &y, nullptr);
+ type = quad_type_for_transformed_rect(m);
+ if (type == GrQuadType::kPerspective) {
+ // While the matrix created perspective, the coordinates were projected to a 2D quad
+ // in map_rect_general since no w V4f was provided.
+ type = GrQuadType::kStandard;
+ }
}
- return GrQuad(x, y);
+ return GrQuad(x, y, type);
}
GrQuad GrQuad::MakeFromSkQuad(const SkPoint pts[4], const SkMatrix& matrix) {
V4f xs, ys;
rearrange_sk_to_gr_points(pts, &xs, &ys);
+ GrQuadType type = quad_type_for_points(pts, matrix);
+ if (type == GrQuadType::kPerspective) {
+ // While the matrix created perspective, the coordinates were projected to a 2D quad
+ // in map_rect_general since no w V4f was provided.
+ type = GrQuadType::kStandard;
+ }
+
if (matrix.isIdentity()) {
- return GrQuad(xs, ys);
+ return GrQuad(xs, ys, type);
} else {
V4f mx, my;
map_quad_general(xs, ys, matrix, &mx, &my, nullptr);
- return GrQuad(mx, my);
+ return GrQuad(mx, my, type);
}
}
@@ -167,7 +184,8 @@
}
// Private constructor used by GrQuadList to quickly fill in a quad's values from the channel arrays
-GrPerspQuad::GrPerspQuad(const float* xs, const float* ys, const float* ws) {
+GrPerspQuad::GrPerspQuad(const float* xs, const float* ys, const float* ws, GrQuadType type)
+ : fType(type) {
memcpy(fX, xs, 4 * sizeof(float));
memcpy(fY, ys, 4 * sizeof(float));
memcpy(fW, ws, 4 * sizeof(float));
@@ -176,24 +194,28 @@
GrPerspQuad GrPerspQuad::MakeFromRect(const SkRect& rect, const SkMatrix& m) {
V4f x, y, w;
SkMatrix::TypeMask tm = m.getType();
+ GrQuadType type;
if (tm <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) {
map_rect_translate_scale(rect, m, &x, &y);
w = 1.f;
+ type = GrQuadType::kRect;
} else {
map_rect_general(rect, m, &x, &y, &w);
+ type = quad_type_for_transformed_rect(m);
}
- return GrPerspQuad(x, y, w);
+ return GrPerspQuad(x, y, w, type);
}
GrPerspQuad GrPerspQuad::MakeFromSkQuad(const SkPoint pts[4], const SkMatrix& matrix) {
V4f xs, ys;
rearrange_sk_to_gr_points(pts, &xs, &ys);
+ GrQuadType type = quad_type_for_points(pts, matrix);
if (matrix.isIdentity()) {
- return GrPerspQuad(xs, ys, 1.f);
+ return GrPerspQuad(xs, ys, 1.f, type);
} else {
V4f mx, my, mw;
map_quad_general(xs, ys, matrix, &mx, &my, &mw);
- return GrPerspQuad(mx, my, mw);
+ return GrPerspQuad(mx, my, mw, type);
}
}