blob: 824131b1b47f472f57553c2d70661d8f610f639b [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).
Michael Ludwigf995c052018-11-26 15:24:29 -050023// 2. Is rectilinear - the matrix does not have skew or perspective, but may rotate (unlike #1)
24// 3. Is a quadrilateral - the matrix does not have perspective, but may rotate or skew, or
Michael Ludwig1f7e4382018-10-19 09:36:57 -040025// ws() == all ones.
Michael Ludwigf995c052018-11-26 15:24:29 -050026// 4. Is a perspective quad - the matrix has perspective, subsuming all previous quad types.
Michael Ludwig1f7e4382018-10-19 09:36:57 -040027enum class GrQuadType {
Michael Ludwigc182b942018-11-16 10:27:51 -050028 kRect,
Michael Ludwigf995c052018-11-26 15:24:29 -050029 kRectilinear,
Michael Ludwigc182b942018-11-16 10:27:51 -050030 kStandard,
31 kPerspective,
32 kLast = kPerspective
Michael Ludwig1f7e4382018-10-19 09:36:57 -040033};
Michael Ludwigc182b942018-11-16 10:27:51 -050034static const int kGrQuadTypeCount = static_cast<int>(GrQuadType::kLast) + 1;
Michael Ludwig1f7e4382018-10-19 09:36:57 -040035
36// If an SkRect is transformed by this matrix, what class of quad is required to represent it. Since
37// quadType() is only provided on Gr[Persp]Quad in debug builds, production code should use this
38// to efficiently determine quad types.
39GrQuadType GrQuadTypeForTransformedRect(const SkMatrix& matrix);
40
Michael Ludwig6bee7762018-10-19 09:50:36 -040041// Resolve disagreements between the overall requested AA type and the per-edge quad AA flags.
Michael Ludwigc182b942018-11-16 10:27:51 -050042// knownQuadType must have come from GrQuadTypeForTransformedRect with the matrix that created the
Michael Ludwig6bee7762018-10-19 09:50:36 -040043// provided quad. Both outAAType and outEdgeFlags will be updated.
44template <typename Q>
45void GrResolveAATypeForQuad(GrAAType requestedAAType, GrQuadAAFlags requestedEdgeFlags,
46 const Q& quad, GrQuadType knownQuadType,
47 GrAAType* outAAtype, GrQuadAAFlags* outEdgeFlags);
48
joshualittae5b2c62015-08-19 08:48:41 -070049/**
Brian Salomon57caa662017-10-18 12:21:05 +000050 * GrQuad is a collection of 4 points which can be used to represent an arbitrary quadrilateral. The
51 * points make a triangle strip with CCW triangles (top-left, bottom-left, top-right, bottom-right).
joshualittae5b2c62015-08-19 08:48:41 -070052 */
53class GrQuad {
54public:
Brian Salomona33b67c2018-05-17 10:42:14 -040055 GrQuad() = default;
joshualitt8cce8f12015-08-26 06:23:39 -070056
Brian Salomona33b67c2018-05-17 10:42:14 -040057 GrQuad(const GrQuad& that) = default;
58
59 explicit GrQuad(const SkRect& rect)
60 : fX{rect.fLeft, rect.fLeft, rect.fRight, rect.fRight}
61 , fY{rect.fTop, rect.fBottom, rect.fTop, rect.fBottom} {}
62
63 /** Sets the quad to the rect as transformed by the matrix. */
64 GrQuad(const SkRect&, const SkMatrix&);
65
66 explicit GrQuad(const SkPoint pts[4])
67 : fX{pts[0].fX, pts[1].fX, pts[2].fX, pts[3].fX}
68 , fY{pts[0].fY, pts[1].fY, pts[2].fY, pts[3].fY} {}
69
70 GrQuad& operator=(const GrQuad& that) = default;
71
72 SkPoint point(int i) const { return {fX[i], fY[i]}; }
73
74 SkRect bounds() const {
75 auto x = this->x4f(), y = this->y4f();
76 return {x.min(), y.min(), x.max(), y.max()};
joshualittae5b2c62015-08-19 08:48:41 -070077 }
78
Brian Salomona33b67c2018-05-17 10:42:14 -040079 float x(int i) const { return fX[i]; }
80 float y(int i) const { return fY[i]; }
joshualittae5b2c62015-08-19 08:48:41 -070081
Brian Salomona33b67c2018-05-17 10:42:14 -040082 Sk4f x4f() const { return Sk4f::Load(fX); }
83 Sk4f y4f() const { return Sk4f::Load(fY); }
joshualitt8cce8f12015-08-26 06:23:39 -070084
Michael Ludwig1f7e4382018-10-19 09:36:57 -040085 // True if anti-aliasing affects this quad. Requires quadType() == kRect_QuadType
86 bool aaHasEffectOnRect() const;
87
88#ifdef SK_DEBUG
89 GrQuadType quadType() const;
90#endif
91
joshualittae5b2c62015-08-19 08:48:41 -070092private:
Brian Salomona33b67c2018-05-17 10:42:14 -040093 float fX[4];
94 float fY[4];
joshualittae5b2c62015-08-19 08:48:41 -070095};
96
Brian Salomonbe3c1d22018-05-21 12:54:39 -040097class GrPerspQuad {
98public:
99 GrPerspQuad() = default;
100
101 GrPerspQuad(const SkRect&, const SkMatrix&);
102
103 GrPerspQuad& operator=(const GrPerspQuad&) = default;
104
105 SkPoint3 point(int i) const { return {fX[i], fY[i], fW[i]}; }
106
Brian Salomonb80ffee2018-05-23 16:39:39 -0400107 SkRect bounds() const {
Brian Salomonbe3c1d22018-05-21 12:54:39 -0400108 auto x = this->x4f() * this->iw4f();
109 auto y = this->y4f() * this->iw4f();
110 return {x.min(), y.min(), x.max(), y.max()};
111 }
112
113 float x(int i) const { return fX[i]; }
114 float y(int i) const { return fY[i]; }
115 float w(int i) const { return fW[i]; }
116 float iw(int i) const { return fIW[i]; }
117
118 Sk4f x4f() const { return Sk4f::Load(fX); }
119 Sk4f y4f() const { return Sk4f::Load(fY); }
120 Sk4f w4f() const { return Sk4f::Load(fW); }
121 Sk4f iw4f() const { return Sk4f::Load(fIW); }
122
Michael Ludwig1f7e4382018-10-19 09:36:57 -0400123 bool hasPerspective() const { return (w4f() != Sk4f(1.f)).anyTrue(); }
124
125 // True if anti-aliasing affects this quad. Requires quadType() == kRect_QuadType
126 bool aaHasEffectOnRect() const;
127
128#ifdef SK_DEBUG
129 GrQuadType quadType() const;
130#endif
131
Brian Salomonbe3c1d22018-05-21 12:54:39 -0400132private:
133 float fX[4];
134 float fY[4];
135 float fW[4];
136 float fIW[4]; // 1/w
137};
138
joshualittae5b2c62015-08-19 08:48:41 -0700139#endif