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