• 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/ganesh/SurfaceContext.h"
12 
13 #include "src/gpu/ganesh/ops/OpsTask.h"
14 
15 namespace skgpu::v1 {
16 
17 class SurfaceFillContext : public SurfaceContext {
18 public:
19     SurfaceFillContext(GrRecordingContext* rContext,
20                        GrSurfaceProxyView readView,
21                        GrSurfaceProxyView writeView,
22                        const GrColorInfo& colorInfo);
23 
asFillContext()24     SurfaceFillContext* asFillContext() override { return this; }
25 
26     OpsTask* getOpsTask();
27 
28 #if GR_TEST_UTILS
testingOnly_PeekLastOpsTask()29     OpsTask* testingOnly_PeekLastOpsTask() { return fOpsTask.get(); }
30 #endif
31 
32     /**
33      * Provides a performance hint that the render target's contents are allowed
34      * to become undefined.
35      */
36     void discard();
37 
38     void resolveMSAA();
39 
40     /**
41      * Clear the rect of the render target to the given color.
42      * @param rect  the rect to clear to
43      * @param color the color to clear to.
44      */
45     template <SkAlphaType AlphaType>
clear(const SkIRect & rect,const SkRGBA4f<AlphaType> & color)46     void clear(const SkIRect& rect, const SkRGBA4f<AlphaType>& color) {
47         this->internalClear(&rect, this->adjustColorAlphaType(color));
48     }
49 
50     /** Clears the entire render target to the color. */
clear(const SkRGBA4f<AlphaType> & color)51     template <SkAlphaType AlphaType> void clear(const SkRGBA4f<AlphaType>& color) {
52         this->internalClear(nullptr, this->adjustColorAlphaType(color));
53     }
54 
55     /**
56      * Clear at minimum the pixels within 'scissor', but is allowed to clear the full render target
57      * if that is the more performant option.
58      */
59     template <SkAlphaType AlphaType>
clearAtLeast(const SkIRect & scissor,const SkRGBA4f<AlphaType> & color)60     void clearAtLeast(const SkIRect& scissor, const SkRGBA4f<AlphaType>& color) {
61         this->internalClear(&scissor,
62                             this->adjustColorAlphaType(color),
63                             /* upgrade to full */ true);
64     }
65 
66     /** Fills 'dstRect' with 'fp' */
67     void fillRectWithFP(const SkIRect& dstRect, std::unique_ptr<GrFragmentProcessor>);
68 
69     /**
70      * A convenience version of fillRectWithFP that applies a coordinate transformation via
71      * GrMatrixEffect.
72      */
73     void fillRectWithFP(const SkIRect& dstRect,
74                         const SkMatrix& localMatrix,
75                         std::unique_ptr<GrFragmentProcessor>);
76 
77     /** 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)78     void fillRectToRectWithFP(const SkRect& srcRect,
79                               const SkIRect& dstRect,
80                               std::unique_ptr<GrFragmentProcessor> fp) {
81         SkMatrix lm = SkMatrix::RectToRect(SkRect::Make(dstRect), srcRect);
82         this->fillRectWithFP(dstRect, lm, std::move(fp));
83     }
84 
85     /** 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)86     void fillRectToRectWithFP(const SkIRect& srcRect,
87                               const SkIRect& dstRect,
88                               std::unique_ptr<GrFragmentProcessor> fp) {
89         this->fillRectToRectWithFP(SkRect::Make(srcRect), dstRect, std::move(fp));
90     }
91 
92     /** Fills the entire render target with the passed FP. */
fillWithFP(std::unique_ptr<GrFragmentProcessor> fp)93     void fillWithFP(std::unique_ptr<GrFragmentProcessor> fp) {
94         this->fillRectWithFP(SkIRect::MakeSize(fWriteView.proxy()->dimensions()), std::move(fp));
95     }
96 
97     /**
98      * Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height
99      * of the srcRect. The srcRect and dstRect are clipped to the bounds of the src and dst surfaces
100      * respectively.
101      */
102     bool blitTexture(GrSurfaceProxyView,
103                      const SkIRect& srcRect,
104                      const SkIPoint& dstPoint);
105 
106     sk_sp<GrRenderTask> refRenderTask();
107 
numSamples()108     int numSamples() const { return this->asRenderTargetProxy()->numSamples(); }
wrapsVkSecondaryCB()109     bool wrapsVkSecondaryCB() const { return this->asRenderTargetProxy()->wrapsVkSecondaryCB(); }
110 
arenaAlloc()111     SkArenaAlloc* arenaAlloc() { return this->arenas()->arenaAlloc(); }
subRunAlloc()112     sktext::gpu::SubRunAllocator* subRunAlloc() { return this->arenas()->subRunAlloc(); }
113 
writeSurfaceView()114     const GrSurfaceProxyView& writeSurfaceView() const { return fWriteView; }
115 
116 protected:
117     OpsTask* replaceOpsTask();
118 
119     /**
120      * Creates a constant color paint for a clear, using src-over if possible to improve batching.
121      */
122     static void ClearToGrPaint(std::array<float, 4> color, GrPaint* paint);
123 
124     void addOp(GrOp::Owner);
125 
126     template <SkAlphaType AlphaType>
127     static std::array<float, 4> ConvertColor(SkRGBA4f<AlphaType> color);
128 
129     template <SkAlphaType AlphaType>
130     std::array<float, 4> adjustColorAlphaType(SkRGBA4f<AlphaType> color) const;
131 
132     GrSurfaceProxyView fWriteView;
133 
134 private:
arenas()135     sk_sp<GrArenas> arenas() { return fWriteView.proxy()->asRenderTargetProxy()->arenas(); }
136 
137     void addDrawOp(GrOp::Owner);
138 
139     /** Override to be notified in subclass before the current ops task is replaced. */
willReplaceOpsTask(OpsTask * prevTask,OpsTask * nextTask)140     virtual void willReplaceOpsTask(OpsTask* prevTask, OpsTask* nextTask) {}
141 
142     /**
143      * Override to be called to participate in the decision to discard all previous ops if a
144      * fullscreen clear occurs.
145      */
canDiscardPreviousOpsOnFullClear()146     virtual OpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const {
147         return OpsTask::CanDiscardPreviousOps::kYes;
148     }
149 
150     void internalClear(const SkIRect* scissor,
151                        std::array<float, 4> color,
152                        bool upgradePartialToFull = false);
153 
154     SkDEBUGCODE(void onValidate() const override;)
155 
156     // The OpsTask can be closed by some other surface context that has picked it up. For this
157     // reason, the OpsTask should only ever be accessed via 'getOpsTask'.
158     sk_sp<OpsTask> fOpsTask;
159 
160     using INHERITED = SurfaceContext;
161 };
162 
163 template<>
164 inline std::array<float, 4> SurfaceFillContext::ConvertColor<kPremul_SkAlphaType>(
165         SkPMColor4f color) {
166     return color.unpremul().array();
167 }
168 
169 template<>
170 inline std::array<float, 4> SurfaceFillContext::ConvertColor<kUnpremul_SkAlphaType>(
171         SkColor4f color) {
172     return color.premul().array();
173 }
174 
175 template <SkAlphaType AlphaType>
adjustColorAlphaType(SkRGBA4f<AlphaType> color)176 std::array<float, 4> SurfaceFillContext::adjustColorAlphaType(SkRGBA4f<AlphaType> color) const {
177     if (AlphaType == kUnknown_SkAlphaType ||
178         this->colorInfo().alphaType() == kUnknown_SkAlphaType) {
179         return color.array();
180     }
181     return (AlphaType == this->colorInfo().alphaType()) ? color.array() : ConvertColor(color);
182 }
183 
184 } // namespace skgpu::v1
185 
186 #endif // SurfaceFillContext_DEFINED
187