• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
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 skgpu_graphite_DrawParams_DEFINED
9 #define skgpu_graphite_DrawParams_DEFINED
10 
11 
12 #include "include/core/SkPaint.h"
13 #include "include/core/SkRect.h"
14 #include "src/gpu/graphite/DrawOrder.h"
15 #include "src/gpu/graphite/geom/Geometry.h"
16 #include "src/gpu/graphite/geom/Rect.h"
17 #include "src/gpu/graphite/geom/Transform_graphite.h"
18 
19 #include <optional>
20 
21 namespace skgpu::graphite {
22 
23 // NOTE: Only represents the stroke or hairline styles; stroke-and-fill must be handled higher up.
24 class StrokeStyle {
25 public:
StrokeStyle()26     StrokeStyle() : fHalfWidth(0.f), fJoinLimit(0.f), fCap(SkPaint::kButt_Cap) {}
StrokeStyle(float width,float miterLimit,SkPaint::Join join,SkPaint::Cap cap)27     StrokeStyle(float width,
28                 float miterLimit,
29                 SkPaint::Join join,
30                 SkPaint::Cap cap)
31             : fHalfWidth(std::max(0.f, 0.5f * width))
32             , fJoinLimit(join == SkPaint::kMiter_Join ? std::max(0.f, miterLimit) :
33                          (join == SkPaint::kBevel_Join ? 0.f : -1.f))
34             , fCap(cap) {}
35 
36     StrokeStyle(const StrokeStyle&) = default;
37 
38     StrokeStyle& operator=(const StrokeStyle&) = default;
39 
isMiterJoin()40     bool isMiterJoin() const { return fJoinLimit > 0.f;  }
isBevelJoin()41     bool isBevelJoin() const { return fJoinLimit == 0.f; }
isRoundJoin()42     bool isRoundJoin() const { return fJoinLimit < 0.f;  }
43 
halfWidth()44     float         halfWidth()  const { return fHalfWidth;                }
width()45     float         width()      const { return 2.f * fHalfWidth;          }
miterLimit()46     float         miterLimit() const { return std::max(0.f, fJoinLimit); }
cap()47     SkPaint::Cap  cap()        const { return fCap;                      }
join()48     SkPaint::Join join()       const {
49         return fJoinLimit > 0.f ? SkPaint::kMiter_Join :
50                (fJoinLimit == 0.f ? SkPaint::kBevel_Join : SkPaint::kRound_Join);
51     }
52 
53     // Raw join limit, compatible with tess::StrokeParams
joinLimit()54     float joinLimit() const { return fJoinLimit; }
55 
56 private:
57     float        fHalfWidth; // >0: relative to transform; ==0: hairline, 1px in device space
58     float        fJoinLimit; // >0: miter join; ==0: bevel join; <0: round join
59     SkPaint::Cap fCap;
60 };
61 
62 // TBD: Separate DashParams extracted from an SkDashPathEffect? Or folded into StrokeStyle?
63 
64 class Clip {
65 public:
Clip(const Rect & drawBounds,const SkIRect & scissor)66     Clip(const Rect& drawBounds, const SkIRect& scissor)
67             : fDrawBounds(drawBounds)
68             , fScissor(scissor) {}
69 
drawBounds()70     const Rect&    drawBounds() const { return fDrawBounds; }
scissor()71     const SkIRect& scissor()    const { return fScissor;    }
72 
73 private:
74     // Draw bounds represent the tight bounds of the draw, including any padding/outset for stroking
75     // and intersected with the scissor.
76     // - DrawList assumes the DrawBounds are correct for a given shape, transform, and style. They
77     //   are provided to the DrawList to avoid re-calculating the same bounds.
78     Rect    fDrawBounds;
79     // The scissor must contain fDrawBounds, and must already be intersected with the device bounds.
80     SkIRect fScissor;
81     // TODO: If we add more complex analytic shapes for clipping, e.g. coverage rrect, it should
82     // go here.
83 };
84 
85 // Encapsulates all geometric state for a single high-level draw call. RenderSteps are responsible
86 // for transforming this state into actual rendering; shading from PaintParams is handled separately
87 class DrawParams {
88 public:
DrawParams(const Transform & transform,const Geometry & geometry,const Clip & clip,DrawOrder drawOrder,const StrokeStyle * stroke)89     DrawParams(const Transform& transform,
90                const Geometry& geometry,
91                const Clip& clip,
92                DrawOrder drawOrder,
93                const StrokeStyle* stroke)
94             : fTransform(transform)
95             , fGeometry(geometry)
96             , fClip(clip)
97             , fOrder(drawOrder)
98             , fStroke(stroke ? std::optional<StrokeStyle>(*stroke) : std::nullopt) {}
99 
transform()100     const Transform& transform() const { return fTransform; }
geometry()101     const Geometry&  geometry()  const { return fGeometry;  }
clip()102     const Clip&      clip()      const { return fClip;      }
order()103     DrawOrder        order()     const { return fOrder;     }
104 
105     // Optional stroke parameters if the geometry is stroked instead of filled
isStroke()106     bool isStroke() const { return fStroke.has_value(); }
strokeStyle()107     const StrokeStyle& strokeStyle() const {
108         SkASSERT(this->isStroke());
109         return *fStroke;
110     }
111 
112 private:
113     const Transform& fTransform; // Lifetime of the transform must be held longer than the geometry
114 
115     Geometry  fGeometry;
116     Clip      fClip;
117     DrawOrder fOrder;
118 
119     std::optional<StrokeStyle> fStroke; // Not present implies fill
120 };
121 
122 }  // namespace skgpu::graphite
123 
124 #endif // skgpu_graphite_DrawParams_DEFINED
125