xref: /aosp_15_r20/external/skia/src/gpu/graphite/geom/EdgeAAQuad.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2023 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef skgpu_graphite_geom_EdgeAAQuad_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define skgpu_graphite_geom_EdgeAAQuad_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkEnumBitMask.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkVx.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/geom/Rect.h"
16*c8dee2aaSAndroid Build Coastguard Worker 
17*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
18*c8dee2aaSAndroid Build Coastguard Worker 
19*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker /**
22*c8dee2aaSAndroid Build Coastguard Worker  * EdgeAAQuad contains (x,y) coordinates for the four corners of a quadrilateral, assumed to be
23*c8dee2aaSAndroid Build Coastguard Worker  * convex and in a consistent winding (CW vs. CCW is fine). Locally, the vertices are ordered
24*c8dee2aaSAndroid Build Coastguard Worker  * "top-left", "top-right", "bottom-right", "bottom-left". The edges are in order left (p0-p3),
25*c8dee2aaSAndroid Build Coastguard Worker  * top (p1-p0), right (p2-p1), and bottom (p3-p2).
26*c8dee2aaSAndroid Build Coastguard Worker  */
27*c8dee2aaSAndroid Build Coastguard Worker class EdgeAAQuad {
28*c8dee2aaSAndroid Build Coastguard Worker public:
29*c8dee2aaSAndroid Build Coastguard Worker     // SkEnumBitMask<Flags> is a typesafe equivalent to SkCanvas::QuadAAFlags.
30*c8dee2aaSAndroid Build Coastguard Worker     enum class Flags : uint8_t {
31*c8dee2aaSAndroid Build Coastguard Worker         kLeft   = 0b0001,
32*c8dee2aaSAndroid Build Coastguard Worker         kTop    = 0b0010,
33*c8dee2aaSAndroid Build Coastguard Worker         kRight  = 0b0100,
34*c8dee2aaSAndroid Build Coastguard Worker         kBottom = 0b1000,
35*c8dee2aaSAndroid Build Coastguard Worker 
36*c8dee2aaSAndroid Build Coastguard Worker         kNone   = 0b0000,
37*c8dee2aaSAndroid Build Coastguard Worker         kAll    = 0b1111,
38*c8dee2aaSAndroid Build Coastguard Worker     };
39*c8dee2aaSAndroid Build Coastguard Worker 
40*c8dee2aaSAndroid Build Coastguard Worker     EdgeAAQuad() = delete;
41*c8dee2aaSAndroid Build Coastguard Worker 
EdgeAAQuad(const SkRect & rect,SkEnumBitMask<Flags> edgeFlags)42*c8dee2aaSAndroid Build Coastguard Worker     EdgeAAQuad(const SkRect& rect, SkEnumBitMask<Flags> edgeFlags)
43*c8dee2aaSAndroid Build Coastguard Worker             : fXs{rect.fLeft, rect.fRight, rect.fRight, rect.fLeft}
44*c8dee2aaSAndroid Build Coastguard Worker             , fYs{rect.fTop, rect.fTop, rect.fBottom, rect.fBottom}
45*c8dee2aaSAndroid Build Coastguard Worker             , fEdgeFlags(edgeFlags)
46*c8dee2aaSAndroid Build Coastguard Worker             , fIsRect(true) {}
EdgeAAQuad(const Rect & rect,SkEnumBitMask<Flags> edgeFlags)47*c8dee2aaSAndroid Build Coastguard Worker     EdgeAAQuad(const Rect& rect, SkEnumBitMask<Flags> edgeFlags)
48*c8dee2aaSAndroid Build Coastguard Worker             : fXs{skvx::shuffle<0,2,2,0>(rect.ltrb())}
49*c8dee2aaSAndroid Build Coastguard Worker             , fYs{skvx::shuffle<1,1,3,3>(rect.ltrb())}
50*c8dee2aaSAndroid Build Coastguard Worker             , fEdgeFlags(edgeFlags)
51*c8dee2aaSAndroid Build Coastguard Worker             , fIsRect(true) {}
EdgeAAQuad(const SkPoint points[4],SkEnumBitMask<Flags> edgeFlags)52*c8dee2aaSAndroid Build Coastguard Worker     EdgeAAQuad(const SkPoint points[4], SkEnumBitMask<Flags> edgeFlags)
53*c8dee2aaSAndroid Build Coastguard Worker             : fXs{points[0].fX, points[1].fX, points[2].fX, points[3].fX}
54*c8dee2aaSAndroid Build Coastguard Worker             , fYs{points[0].fY, points[1].fY, points[2].fY, points[3].fY}
55*c8dee2aaSAndroid Build Coastguard Worker             , fEdgeFlags(edgeFlags)
56*c8dee2aaSAndroid Build Coastguard Worker             , fIsRect(false) {}
EdgeAAQuad(const skvx::float4 & xs,const skvx::float4 & ys,SkEnumBitMask<Flags> edgeFlags)57*c8dee2aaSAndroid Build Coastguard Worker     EdgeAAQuad(const skvx::float4& xs, const skvx::float4& ys, SkEnumBitMask<Flags> edgeFlags)
58*c8dee2aaSAndroid Build Coastguard Worker             : fXs(xs)
59*c8dee2aaSAndroid Build Coastguard Worker             , fYs(ys)
60*c8dee2aaSAndroid Build Coastguard Worker             , fEdgeFlags(edgeFlags)
61*c8dee2aaSAndroid Build Coastguard Worker             , fIsRect(false) {}
62*c8dee2aaSAndroid Build Coastguard Worker 
63*c8dee2aaSAndroid Build Coastguard Worker     // The bounding box of the quadrilateral (not counting any outsetting for anti-aliasing).
bounds()64*c8dee2aaSAndroid Build Coastguard Worker     Rect bounds() const {
65*c8dee2aaSAndroid Build Coastguard Worker         if (fIsRect) {
66*c8dee2aaSAndroid Build Coastguard Worker             return Rect({fXs[0], fYs[0]}, {fXs[2], fYs[2]});
67*c8dee2aaSAndroid Build Coastguard Worker         }
68*c8dee2aaSAndroid Build Coastguard Worker 
69*c8dee2aaSAndroid Build Coastguard Worker         Rect p0p1 = Rect::LTRB(skvx::shuffle<0,2,1,3>(skvx::float4(fXs.lo, fYs.lo))).makeSorted();
70*c8dee2aaSAndroid Build Coastguard Worker         Rect p2p3 = Rect::LTRB(skvx::shuffle<0,2,1,3>(skvx::float4(fXs.hi, fYs.hi))).makeSorted();
71*c8dee2aaSAndroid Build Coastguard Worker         return p0p1.makeJoin(p2p3);
72*c8dee2aaSAndroid Build Coastguard Worker     }
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker     // Access the individual elements of the quad data.
xs()75*c8dee2aaSAndroid Build Coastguard Worker     const skvx::float4& xs() const { return fXs; }
ys()76*c8dee2aaSAndroid Build Coastguard Worker     const skvx::float4& ys() const { return fYs; }
edgeFlags()77*c8dee2aaSAndroid Build Coastguard Worker     SkEnumBitMask<Flags> edgeFlags() const { return fEdgeFlags; }
78*c8dee2aaSAndroid Build Coastguard Worker 
isRect()79*c8dee2aaSAndroid Build Coastguard Worker     bool isRect() const { return fIsRect; }
80*c8dee2aaSAndroid Build Coastguard Worker 
81*c8dee2aaSAndroid Build Coastguard Worker private:
82*c8dee2aaSAndroid Build Coastguard Worker     skvx::float4 fXs;
83*c8dee2aaSAndroid Build Coastguard Worker     skvx::float4 fYs;
84*c8dee2aaSAndroid Build Coastguard Worker     SkEnumBitMask<Flags> fEdgeFlags;
85*c8dee2aaSAndroid Build Coastguard Worker     bool fIsRect;
86*c8dee2aaSAndroid Build Coastguard Worker };
87*c8dee2aaSAndroid Build Coastguard Worker 
88*c8dee2aaSAndroid Build Coastguard Worker SK_MAKE_BITMASK_OPS(EdgeAAQuad::Flags)
89*c8dee2aaSAndroid Build Coastguard Worker 
90*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
91*c8dee2aaSAndroid Build Coastguard Worker 
92*c8dee2aaSAndroid Build Coastguard Worker #endif // skgpu_graphite_geom_EdgeAAQuad_DEFINED
93