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