• 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     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