blob: 5f62682ef865e644e20e9d619b86ea02d447e0e5 [file] [log] [blame]
joshualittae5b2c62015-08-19 08:48:41 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrQuad_DEFINED
9#define GrQuad_DEFINED
10
joshualittae5b2c62015-08-19 08:48:41 -070011#include "SkMatrix.h"
Brian Salomona33b67c2018-05-17 10:42:14 -040012#include "SkNx.h"
13#include "SkPoint.h"
Brian Salomonbe3c1d22018-05-21 12:54:39 -040014#include "SkPoint3.h"
joshualittae5b2c62015-08-19 08:48:41 -070015
Michael Ludwig6bee7762018-10-19 09:50:36 -040016enum class GrAAType : unsigned;
17enum class GrQuadAAFlags;
18
Michael Ludwig1f7e4382018-10-19 09:36:57 -040019// Rectangles transformed by matrices (view or local) can be classified in three ways:
20// 1. Stays a rectangle - the matrix rectStaysRect() is true, or x(0) == x(1) && x(2) == x(3)
21// and y(0) == y(2) && y(1) == y(3). Or under mirrors, x(0) == x(2) && x(1) == x(3) and
22// y(0) == y(1) && y(2) == y(3).
23// 2. Is a quadrilateral - the matrix does not have perspective, but may rotate or skew, or
24// ws() == all ones.
25// 3. Is a perspective quad - the matrix has perspective, subsuming all previous quad types.
26enum class GrQuadType {
Michael Ludwigc182b942018-11-16 10:27:51 -050027 kRect,
28 kStandard,
29 kPerspective,
30 kLast = kPerspective
Michael Ludwig1f7e4382018-10-19 09:36:57 -040031};
Michael Ludwigc182b942018-11-16 10:27:51 -050032static const int kGrQuadTypeCount = static_cast<int>(GrQuadType::kLast) + 1;
Michael Ludwig1f7e4382018-10-19 09:36:57 -040033
34// If an SkRect is transformed by this matrix, what class of quad is required to represent it. Since
35// quadType() is only provided on Gr[Persp]Quad in debug builds, production code should use this
36// to efficiently determine quad types.
37GrQuadType GrQuadTypeForTransformedRect(const SkMatrix& matrix);
38
Michael Ludwig6bee7762018-10-19 09:50:36 -040039// Resolve disagreements between the overall requested AA type and the per-edge quad AA flags.
Michael Ludwigc182b942018-11-16 10:27:51 -050040// knownQuadType must have come from GrQuadTypeForTransformedRect with the matrix that created the
Michael Ludwig6bee7762018-10-19 09:50:36 -040041// provided quad. Both outAAType and outEdgeFlags will be updated.
42template <typename Q>
43void GrResolveAATypeForQuad(GrAAType requestedAAType, GrQuadAAFlags requestedEdgeFlags,
44 const Q& quad, GrQuadType knownQuadType,
45 GrAAType* outAAtype, GrQuadAAFlags* outEdgeFlags);
46
joshualittae5b2c62015-08-19 08:48:41 -070047/**
Brian Salomon57caa662017-10-18 12:21:05 +000048 * GrQuad is a collection of 4 points which can be used to represent an arbitrary quadrilateral. The
49 * points make a triangle strip with CCW triangles (top-left, bottom-left, top-right, bottom-right).
joshualittae5b2c62015-08-19 08:48:41 -070050 */
51class GrQuad {
52public:
Brian Salomona33b67c2018-05-17 10:42:14 -040053 GrQuad() = default;
joshualitt8cce8f12015-08-26 06:23:39 -070054
Brian Salomona33b67c2018-05-17 10:42:14 -040055 GrQuad(const GrQuad& that) = default;
56
57 explicit GrQuad(const SkRect& rect)
58 : fX{rect.fLeft, rect.fLeft, rect.fRight, rect.fRight}
59 , fY{rect.fTop, rect.fBottom, rect.fTop, rect.fBottom} {}
60
61 /** Sets the quad to the rect as transformed by the matrix. */
62 GrQuad(const SkRect&, const SkMatrix&);
63
64 explicit GrQuad(const SkPoint pts[4])
65 : fX{pts[0].fX, pts[1].fX, pts[2].fX, pts[3].fX}
66 , fY{pts[0].fY, pts[1].fY, pts[2].fY, pts[3].fY} {}
67
68 GrQuad& operator=(const GrQuad& that) = default;
69
70 SkPoint point(int i) const { return {fX[i], fY[i]}; }
71
72 SkRect bounds() const {
73 auto x = this->x4f(), y = this->y4f();
74 return {x.min(), y.min(), x.max(), y.max()};
joshualittae5b2c62015-08-19 08:48:41 -070075 }
76
Brian Salomona33b67c2018-05-17 10:42:14 -040077 float x(int i) const { return fX[i]; }
78 float y(int i) const { return fY[i]; }
joshualittae5b2c62015-08-19 08:48:41 -070079
Brian Salomona33b67c2018-05-17 10:42:14 -040080 Sk4f x4f() const { return Sk4f::Load(fX); }
81 Sk4f y4f() const { return Sk4f::Load(fY); }
joshualitt8cce8f12015-08-26 06:23:39 -070082
Michael Ludwig1f7e4382018-10-19 09:36:57 -040083 // True if anti-aliasing affects this quad. Requires quadType() == kRect_QuadType
84 bool aaHasEffectOnRect() const;
85
86#ifdef SK_DEBUG
87 GrQuadType quadType() const;
88#endif
89
joshualittae5b2c62015-08-19 08:48:41 -070090private:
Brian Salomona33b67c2018-05-17 10:42:14 -040091 float fX[4];
92 float fY[4];
joshualittae5b2c62015-08-19 08:48:41 -070093};
94
Brian Salomonbe3c1d22018-05-21 12:54:39 -040095class GrPerspQuad {
96public:
97 GrPerspQuad() = default;
98
99 GrPerspQuad(const SkRect&, const SkMatrix&);
100
101 GrPerspQuad& operator=(const GrPerspQuad&) = default;
102
103 SkPoint3 point(int i) const { return {fX[i], fY[i], fW[i]}; }
104
Brian Salomonb80ffee2018-05-23 16:39:39 -0400105 SkRect bounds() const {
Brian Salomonbe3c1d22018-05-21 12:54:39 -0400106 auto x = this->x4f() * this->iw4f();
107 auto y = this->y4f() * this->iw4f();
108 return {x.min(), y.min(), x.max(), y.max()};
109 }
110
111 float x(int i) const { return fX[i]; }
112 float y(int i) const { return fY[i]; }
113 float w(int i) const { return fW[i]; }
114 float iw(int i) const { return fIW[i]; }
115
116 Sk4f x4f() const { return Sk4f::Load(fX); }
117 Sk4f y4f() const { return Sk4f::Load(fY); }
118 Sk4f w4f() const { return Sk4f::Load(fW); }
119 Sk4f iw4f() const { return Sk4f::Load(fIW); }
120
Michael Ludwig1f7e4382018-10-19 09:36:57 -0400121 bool hasPerspective() const { return (w4f() != Sk4f(1.f)).anyTrue(); }
122
123 // True if anti-aliasing affects this quad. Requires quadType() == kRect_QuadType
124 bool aaHasEffectOnRect() const;
125
126#ifdef SK_DEBUG
127 GrQuadType quadType() const;
128#endif
129
Brian Salomonbe3c1d22018-05-21 12:54:39 -0400130private:
131 float fX[4];
132 float fY[4];
133 float fW[4];
134 float fIW[4]; // 1/w
135};
136
joshualittae5b2c62015-08-19 08:48:41 -0700137#endif