blob: 107fe255f0ad76194f598fcfe16fc47d01800aa7 [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 {
27 kRect_QuadType,
28 kStandard_QuadType,
29 kPerspective_QuadType
30};
31
32// If an SkRect is transformed by this matrix, what class of quad is required to represent it. Since
33// quadType() is only provided on Gr[Persp]Quad in debug builds, production code should use this
34// to efficiently determine quad types.
35GrQuadType GrQuadTypeForTransformedRect(const SkMatrix& matrix);
36
Michael Ludwig6bee7762018-10-19 09:50:36 -040037// Resolve disagreements between the overall requested AA type and the per-edge quad AA flags.
38// knownQuadType must have come from GrQuadtypeForTransformedRect with the matrix that created the
39// provided quad. Both outAAType and outEdgeFlags will be updated.
40template <typename Q>
41void GrResolveAATypeForQuad(GrAAType requestedAAType, GrQuadAAFlags requestedEdgeFlags,
42 const Q& quad, GrQuadType knownQuadType,
43 GrAAType* outAAtype, GrQuadAAFlags* outEdgeFlags);
44
joshualittae5b2c62015-08-19 08:48:41 -070045/**
Brian Salomon57caa662017-10-18 12:21:05 +000046 * GrQuad is a collection of 4 points which can be used to represent an arbitrary quadrilateral. The
47 * points make a triangle strip with CCW triangles (top-left, bottom-left, top-right, bottom-right).
joshualittae5b2c62015-08-19 08:48:41 -070048 */
49class GrQuad {
50public:
Brian Salomona33b67c2018-05-17 10:42:14 -040051 GrQuad() = default;
joshualitt8cce8f12015-08-26 06:23:39 -070052
Brian Salomona33b67c2018-05-17 10:42:14 -040053 GrQuad(const GrQuad& that) = default;
54
55 explicit GrQuad(const SkRect& rect)
56 : fX{rect.fLeft, rect.fLeft, rect.fRight, rect.fRight}
57 , fY{rect.fTop, rect.fBottom, rect.fTop, rect.fBottom} {}
58
59 /** Sets the quad to the rect as transformed by the matrix. */
60 GrQuad(const SkRect&, const SkMatrix&);
61
62 explicit GrQuad(const SkPoint pts[4])
63 : fX{pts[0].fX, pts[1].fX, pts[2].fX, pts[3].fX}
64 , fY{pts[0].fY, pts[1].fY, pts[2].fY, pts[3].fY} {}
65
66 GrQuad& operator=(const GrQuad& that) = default;
67
68 SkPoint point(int i) const { return {fX[i], fY[i]}; }
69
70 SkRect bounds() const {
71 auto x = this->x4f(), y = this->y4f();
72 return {x.min(), y.min(), x.max(), y.max()};
joshualittae5b2c62015-08-19 08:48:41 -070073 }
74
Brian Salomona33b67c2018-05-17 10:42:14 -040075 float x(int i) const { return fX[i]; }
76 float y(int i) const { return fY[i]; }
joshualittae5b2c62015-08-19 08:48:41 -070077
Brian Salomona33b67c2018-05-17 10:42:14 -040078 Sk4f x4f() const { return Sk4f::Load(fX); }
79 Sk4f y4f() const { return Sk4f::Load(fY); }
joshualitt8cce8f12015-08-26 06:23:39 -070080
Michael Ludwig1f7e4382018-10-19 09:36:57 -040081 // True if anti-aliasing affects this quad. Requires quadType() == kRect_QuadType
82 bool aaHasEffectOnRect() const;
83
84#ifdef SK_DEBUG
85 GrQuadType quadType() const;
86#endif
87
joshualittae5b2c62015-08-19 08:48:41 -070088private:
Brian Salomona33b67c2018-05-17 10:42:14 -040089 float fX[4];
90 float fY[4];
joshualittae5b2c62015-08-19 08:48:41 -070091};
92
Brian Salomonbe3c1d22018-05-21 12:54:39 -040093class GrPerspQuad {
94public:
95 GrPerspQuad() = default;
96
97 GrPerspQuad(const SkRect&, const SkMatrix&);
98
99 GrPerspQuad& operator=(const GrPerspQuad&) = default;
100
101 SkPoint3 point(int i) const { return {fX[i], fY[i], fW[i]}; }
102
Brian Salomonb80ffee2018-05-23 16:39:39 -0400103 SkRect bounds() const {
Brian Salomonbe3c1d22018-05-21 12:54:39 -0400104 auto x = this->x4f() * this->iw4f();
105 auto y = this->y4f() * this->iw4f();
106 return {x.min(), y.min(), x.max(), y.max()};
107 }
108
109 float x(int i) const { return fX[i]; }
110 float y(int i) const { return fY[i]; }
111 float w(int i) const { return fW[i]; }
112 float iw(int i) const { return fIW[i]; }
113
114 Sk4f x4f() const { return Sk4f::Load(fX); }
115 Sk4f y4f() const { return Sk4f::Load(fY); }
116 Sk4f w4f() const { return Sk4f::Load(fW); }
117 Sk4f iw4f() const { return Sk4f::Load(fIW); }
118
Michael Ludwig1f7e4382018-10-19 09:36:57 -0400119 bool hasPerspective() const { return (w4f() != Sk4f(1.f)).anyTrue(); }
120
121 // True if anti-aliasing affects this quad. Requires quadType() == kRect_QuadType
122 bool aaHasEffectOnRect() const;
123
124#ifdef SK_DEBUG
125 GrQuadType quadType() const;
126#endif
127
Brian Salomonbe3c1d22018-05-21 12:54:39 -0400128private:
129 float fX[4];
130 float fY[4];
131 float fW[4];
132 float fIW[4]; // 1/w
133};
134
joshualittae5b2c62015-08-19 08:48:41 -0700135#endif