1 /*
2 * Copyright 2021 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 SurfaceFillContext_DEFINED
9 #define SurfaceFillContext_DEFINED
10
11 #include "src/gpu/SurfaceContext.h"
12
13 namespace skgpu {
14
15 class SurfaceFillContext : public SurfaceContext {
16 public:
17
asFillContext()18 SurfaceFillContext* asFillContext() override { return this; }
19
20 /**
21 * Provides a performance hint that the render target's contents are allowed
22 * to become undefined.
23 */
24 virtual void discard() = 0;
25
26 virtual void resolveMSAA() = 0;
27
28 /**
29 * Clear the rect of the render target to the given color.
30 * @param rect the rect to clear to
31 * @param color the color to clear to.
32 */
33 template <SkAlphaType AlphaType>
clear(const SkIRect & rect,const SkRGBA4f<AlphaType> & color)34 void clear(const SkIRect& rect, const SkRGBA4f<AlphaType>& color) {
35 this->internalClear(&rect, this->adjustColorAlphaType(color));
36 }
37
38 /** Clears the entire render target to the color. */
clear(const SkRGBA4f<AlphaType> & color)39 template <SkAlphaType AlphaType> void clear(const SkRGBA4f<AlphaType>& color) {
40 this->internalClear(nullptr, this->adjustColorAlphaType(color));
41 }
42
43 /**
44 * Clear at minimum the pixels within 'scissor', but is allowed to clear the full render target
45 * if that is the more performant option.
46 */
47 template <SkAlphaType AlphaType>
clearAtLeast(const SkIRect & scissor,const SkRGBA4f<AlphaType> & color)48 void clearAtLeast(const SkIRect& scissor, const SkRGBA4f<AlphaType>& color) {
49 this->internalClear(&scissor,
50 this->adjustColorAlphaType(color),
51 /* upgrade to full */ true);
52 }
53
54 /** Fills 'dstRect' with 'fp' */
55 virtual void fillRectWithFP(const SkIRect& dstRect, std::unique_ptr<GrFragmentProcessor>) = 0;
56
57 /**
58 * A convenience version of fillRectWithFP that applies a coordinate transformation via
59 * GrMatrixEffect.
60 */
61 void fillRectWithFP(const SkIRect& dstRect,
62 const SkMatrix& localMatrix,
63 std::unique_ptr<GrFragmentProcessor>);
64
65 /** Fills 'dstRect' with 'fp' using a local matrix that maps 'srcRect' to 'dstRect' */
fillRectToRectWithFP(const SkRect & srcRect,const SkIRect & dstRect,std::unique_ptr<GrFragmentProcessor> fp)66 void fillRectToRectWithFP(const SkRect& srcRect,
67 const SkIRect& dstRect,
68 std::unique_ptr<GrFragmentProcessor> fp) {
69 SkMatrix lm = SkMatrix::RectToRect(SkRect::Make(dstRect), srcRect);
70 this->fillRectWithFP(dstRect, lm, std::move(fp));
71 }
72
73 /** Fills 'dstRect' with 'fp' using a local matrix that maps 'srcRect' to 'dstRect' */
fillRectToRectWithFP(const SkIRect & srcRect,const SkIRect & dstRect,std::unique_ptr<GrFragmentProcessor> fp)74 void fillRectToRectWithFP(const SkIRect& srcRect,
75 const SkIRect& dstRect,
76 std::unique_ptr<GrFragmentProcessor> fp) {
77 this->fillRectToRectWithFP(SkRect::Make(srcRect), dstRect, std::move(fp));
78 }
79
80 /** Fills the entire render target with the passed FP. */
fillWithFP(std::unique_ptr<GrFragmentProcessor> fp)81 void fillWithFP(std::unique_ptr<GrFragmentProcessor> fp) {
82 this->fillRectWithFP(SkIRect::MakeSize(fWriteView.proxy()->dimensions()), std::move(fp));
83 }
84
85 /**
86 * A convenience version of fillWithFP that applies a coordinate transformation via
87 * GrMatrixEffect and fills the entire render target.
88 */
fillWithFP(const SkMatrix & localMatrix,std::unique_ptr<GrFragmentProcessor> fp)89 void fillWithFP(const SkMatrix& localMatrix, std::unique_ptr<GrFragmentProcessor> fp) {
90 this->fillRectWithFP(SkIRect::MakeSize(fWriteView.proxy()->dimensions()),
91 localMatrix,
92 std::move(fp));
93 }
94
95 /**
96 * Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height
97 * of the srcRect. The srcRect and dstRect are clipped to the bounds of the src and dst surfaces
98 * respectively.
99 */
100 virtual bool blitTexture(GrSurfaceProxyView,
101 const SkIRect& srcRect,
102 const SkIPoint& dstPoint) = 0;
103
104 virtual sk_sp<GrRenderTask> refRenderTask() = 0;
105
106 protected:
SurfaceFillContext(GrRecordingContext * rContext,GrSurfaceProxyView readView,GrSurfaceProxyView writeView,const GrColorInfo & colorInfo)107 SurfaceFillContext(GrRecordingContext* rContext,
108 GrSurfaceProxyView readView,
109 GrSurfaceProxyView writeView,
110 const GrColorInfo& colorInfo)
111 : SurfaceContext(rContext, std::move(readView), colorInfo)
112 , fWriteView(std::move(writeView)) {
113 SkASSERT(this->asSurfaceProxy() == fWriteView.proxy());
114 SkASSERT(this->origin() == fWriteView.origin());
115 }
116
117 template <SkAlphaType AlphaType>
118 static std::array<float, 4> ConvertColor(SkRGBA4f<AlphaType> color);
119
120 template <SkAlphaType AlphaType>
121 std::array<float, 4> adjustColorAlphaType(SkRGBA4f<AlphaType> color) const;
122
123 GrSurfaceProxyView fWriteView;
124
125 private:
126 virtual void internalClear(const SkIRect* scissor,
127 std::array<float, 4> color,
128 bool upgradePartialToFull = false) = 0;
129
130 using INHERITED = SurfaceContext;
131 };
132
133 template<>
134 inline std::array<float, 4> SurfaceFillContext::ConvertColor<kPremul_SkAlphaType>(
135 SkPMColor4f color) {
136 return color.unpremul().array();
137 }
138
139 template<>
140 inline std::array<float, 4> SurfaceFillContext::ConvertColor<kUnpremul_SkAlphaType>(
141 SkColor4f color) {
142 return color.premul().array();
143 }
144
145 template <SkAlphaType AlphaType>
adjustColorAlphaType(SkRGBA4f<AlphaType> color)146 std::array<float, 4> SurfaceFillContext::adjustColorAlphaType(SkRGBA4f<AlphaType> color) const {
147 if (AlphaType == kUnknown_SkAlphaType ||
148 this->colorInfo().alphaType() == kUnknown_SkAlphaType) {
149 return color.array();
150 }
151 return (AlphaType == this->colorInfo().alphaType()) ? color.array() : ConvertColor(color);
152 }
153
154 } // namespace skgpu
155
156 #endif // SurfaceFillContext_DEFINED
157