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