• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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 GrSurfaceFillContext_DEFINED
9 #define GrSurfaceFillContext_DEFINED
10 
11 #include "include/core/SkSize.h"
12 #include "include/private/GrTypesPriv.h"
13 #include "src/gpu/GrImageInfo.h"
14 #include "src/gpu/GrOpsTask.h"
15 #include "src/gpu/GrSurfaceContext.h"
16 #include "src/gpu/GrSwizzle.h"
17 #include "src/gpu/effects/GrMatrixEffect.h"
18 
19 #include <array>
20 #include <tuple>
21 
22 class GrFragmentProcessor;
23 class GrImageContext;
24 class GrOp;
25 class GrBackendFormat;
26 class GrRecordingContext;
27 class GrSurfaceProxyView;
28 class SkColorSpace;
29 
30 class GrSurfaceFillContext : public GrSurfaceContext {
31 public:
32     /**
33      * Checks whether the passed color type is renderable with the passed context. If so, the
34      * same color type is passed back along with the default format used for the color type. If
35      * not, provides an alternative (perhaps lower bit depth and/or unorm instead of float) color
36      * type that is supported along with it's default format or kUnknown if there no renderable
37      * fallback format.
38      */
39     static std::tuple<GrColorType, GrBackendFormat> GetFallbackColorTypeAndFormat(GrImageContext*,
40                                                                                   GrColorType,
41                                                                                   int sampleCount);
42 
43     GrSurfaceFillContext(GrRecordingContext*,
44                          GrSurfaceProxyView readView,
45                          GrSurfaceProxyView writeView,
46                          const GrColorInfo&,
47                          bool flushTimeOpsTask = false);
48 
49     /**
50      * Uses GrImageInfo's color type to pick the default texture format. Will return a
51      * GrSurfaceDrawContext if possible.
52      */
53     static std::unique_ptr<GrSurfaceFillContext> Make(GrRecordingContext*,
54                                                       GrImageInfo,
55                                                       SkBackingFit = SkBackingFit::kExact,
56                                                       int sampleCount = 1,
57                                                       GrMipmapped = GrMipmapped::kNo,
58                                                       GrProtected = GrProtected::kNo,
59                                                       GrSurfaceOrigin = kTopLeft_GrSurfaceOrigin,
60                                                       SkBudgeted = SkBudgeted::kYes);
61 
62     /**
63      * Like the above but uses GetFallbackColorTypeAndFormat to find a fallback color type (and
64      * compatible format) if the passed GrImageInfo's color type is not renderable.
65      */
66     static std::unique_ptr<GrSurfaceFillContext> MakeWithFallback(
67             GrRecordingContext*,
68             GrImageInfo,
69             SkBackingFit = SkBackingFit::kExact,
70             int sampleCount = 1,
71             GrMipmapped = GrMipmapped::kNo,
72             GrProtected = GrProtected::kNo,
73             GrSurfaceOrigin = kTopLeft_GrSurfaceOrigin,
74             SkBudgeted = SkBudgeted::kYes);
75 
76     /**
77      * Makes a custom configured GrSurfaceFillContext where the caller specifies the specific
78      * texture format and swizzles. The color type will be kUnknown. Returns a GrSurfaceDrawContext
79      * if possible.
80      */
81     static std::unique_ptr<GrSurfaceFillContext> Make(GrRecordingContext*,
82                                                       SkAlphaType,
83                                                       sk_sp<SkColorSpace>,
84                                                       SkISize dimensions,
85                                                       SkBackingFit,
86                                                       const GrBackendFormat&,
87                                                       int sampleCount,
88                                                       GrMipmapped,
89                                                       GrProtected,
90                                                       GrSwizzle readSwizzle,
91                                                       GrSwizzle writeSwizzle,
92                                                       GrSurfaceOrigin,
93                                                       SkBudgeted);
94 
95     /**
96      * Creates a GrSurfaceFillContext from an existing GrBackendTexture. The GrColorInfo's color
97      * type must be compatible with backend texture's format or this will fail. All formats are
98      * considered compatible with kUnknown. Returns a GrSurfaceDrawContext if possible.
99      */
100     static std::unique_ptr<GrSurfaceFillContext> MakeFromBackendTexture(
101             GrRecordingContext*,
102             GrColorInfo,
103             const GrBackendTexture&,
104             int sampleCount,
105             GrSurfaceOrigin,
106             sk_sp<GrRefCntedCallback> releaseHelper);
107 
asFillContext()108     GrSurfaceFillContext* asFillContext() override { return this; }
109 
110     /**
111      * Provides a performance hint that the render target's contents are allowed
112      * to become undefined.
113      */
114     void discard();
115 
116     /**
117      * Clear the rect of the render target to the given color.
118      * @param rect  the rect to clear to
119      * @param color the color to clear to.
120      */
121     template <SkAlphaType AlphaType>
clear(const SkIRect & rect,const SkRGBA4f<AlphaType> & color)122     void clear(const SkIRect& rect, const SkRGBA4f<AlphaType>& color) {
123         this->internalClear(&rect, this->adjustColorAlphaType(color));
124     }
125 
126     /** Clears the entire render target to the color. */
clear(const SkRGBA4f<AlphaType> & color)127     template <SkAlphaType AlphaType> void clear(const SkRGBA4f<AlphaType>& color) {
128         this->internalClear(nullptr, this->adjustColorAlphaType(color));
129     }
130 
131     /**
132      * Clear at minimum the pixels within 'scissor', but is allowed to clear the full render target
133      * if that is the more performant option.
134      */
135     template <SkAlphaType AlphaType>
clearAtLeast(const SkIRect & scissor,const SkRGBA4f<AlphaType> & color)136     void clearAtLeast(const SkIRect& scissor, const SkRGBA4f<AlphaType>& color) {
137         this->internalClear(&scissor,
138                             this->adjustColorAlphaType(color),
139                             /* upgrade to full */ true);
140     }
141 
142     /** Fills 'dstRect' with 'fp' */
143     void fillRectWithFP(const SkIRect& dstRect, std::unique_ptr<GrFragmentProcessor> fp);
144 
145     /**
146      * A convenience version of fillRectWithFP that applies a coordinate transformation via
147      * GrMatrixEffect.
148      */
fillRectWithFP(const SkIRect & dstRect,const SkMatrix & localMatrix,std::unique_ptr<GrFragmentProcessor> fp)149     void fillRectWithFP(const SkIRect& dstRect,
150                         const SkMatrix& localMatrix,
151                         std::unique_ptr<GrFragmentProcessor> fp) {
152         fp = GrMatrixEffect::Make(localMatrix, std::move(fp));
153         this->fillRectWithFP(dstRect, std::move(fp));
154     }
155 
156     /** 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)157     void fillRectToRectWithFP(const SkRect& srcRect,
158                               const SkIRect& dstRect,
159                               std::unique_ptr<GrFragmentProcessor> fp) {
160         SkMatrix lm = SkMatrix::RectToRect(SkRect::Make(dstRect), srcRect);
161         this->fillRectWithFP(dstRect, lm, std::move(fp));
162     }
163 
164     /** 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)165     void fillRectToRectWithFP(const SkIRect& srcRect,
166                               const SkIRect& dstRect,
167                               std::unique_ptr<GrFragmentProcessor> fp) {
168         this->fillRectToRectWithFP(SkRect::Make(srcRect), dstRect, std::move(fp));
169     }
170 
171     /** Fills the entire render target with the passed FP. */
fillWithFP(std::unique_ptr<GrFragmentProcessor> fp)172     void fillWithFP(std::unique_ptr<GrFragmentProcessor> fp) {
173         this->fillRectWithFP(SkIRect::MakeSize(fWriteView.proxy()->dimensions()), std::move(fp));
174     }
175 
176     /**
177      * A convenience version of fillWithFP that applies a coordinate transformation via
178      * GrMatrixEffect and fills the entire render target.
179      */
fillWithFP(const SkMatrix & localMatrix,std::unique_ptr<GrFragmentProcessor> fp)180     void fillWithFP(const SkMatrix& localMatrix, std::unique_ptr<GrFragmentProcessor> fp) {
181         this->fillRectWithFP(
182                 SkIRect::MakeSize(fWriteView.proxy()->dimensions()), localMatrix, std::move(fp));
183     }
184 
185     /**
186      * Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height
187      * of the srcRect. The srcRect and dstRect are clipped to the bounds of the src and dst surfaces
188      * respectively.
189      */
190     bool blitTexture(GrSurfaceProxyView view, const SkIRect& srcRect, const SkIPoint& dstPoint);
191 
192     GrOpsTask* getOpsTask();
193 
numSamples()194     int numSamples() const { return this->asRenderTargetProxy()->numSamples(); }
wrapsVkSecondaryCB()195     bool wrapsVkSecondaryCB() const { return this->asRenderTargetProxy()->wrapsVkSecondaryCB(); }
196     GrMipmapped mipmapped() const;
197 
arenaAlloc()198     SkArenaAlloc* arenaAlloc() { return this->arenas()->arenaAlloc(); }
subRunAlloc()199     GrSubRunAllocator* subRunAlloc() { return this->arenas()->subRunAlloc(); }
200 
201 #if GR_TEST_UTILS
testingOnly_PeekLastOpsTask()202     GrOpsTask* testingOnly_PeekLastOpsTask() { return fOpsTask.get(); }
203 #endif
204 
writeSurfaceView()205     const GrSurfaceProxyView& writeSurfaceView() const { return fWriteView; }
206 
207 protected:
208     /**
209      * Creates a constant color paint for a clear, using src-over if possible to improve batching.
210      */
211     static void ClearToGrPaint(std::array<float, 4> color, GrPaint* paint);
212 
213     void addOp(GrOp::Owner);
214 
215 private:
arenas()216     sk_sp<GrArenas> arenas() { return fWriteView.proxy()->asRenderTargetProxy()->arenas(); }
217 
218     template <SkAlphaType AlphaType>
219     static std::array<float, 4> ConvertColor(SkRGBA4f<AlphaType> color);
220 
221     template <SkAlphaType AlphaType>
222     std::array<float, 4> adjustColorAlphaType(SkRGBA4f<AlphaType> color) const;
223 
224     /** Override to be notified in subclass before the current ops task is replaced. */
willReplaceOpsTask(GrOpsTask * prevTask,GrOpsTask * nextTask)225     virtual void willReplaceOpsTask(GrOpsTask* prevTask, GrOpsTask* nextTask) {}
226 
227     /**
228      * Override to be called to participate in the decision to discard all previous ops if a
229      * fullscreen clear occurs.
230      */
canDiscardPreviousOpsOnFullClear()231     virtual GrOpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const {
232         return GrOpsTask::CanDiscardPreviousOps::kYes;
233     }
234 
235     void internalClear(const SkIRect* scissor,
236                        std::array<float, 4> color,
237                        bool upgradePartialToFull = false);
238 
239     void addDrawOp(GrOp::Owner);
240 
241     SkDEBUGCODE(void onValidate() const override;)
242 
243     GrSurfaceProxyView fWriteView;
244 
245     // The GrOpsTask can be closed by some other surface context that has picked it up. For this
246     // reason, the GrOpsTask should only ever be accessed via 'getOpsTask'.
247     sk_sp<GrOpsTask> fOpsTask;
248 
249     bool fFlushTimeOpsTask;
250 
251     using INHERITED = GrSurfaceContext;
252 };
253 
254 template<>
255 inline std::array<float, 4> GrSurfaceFillContext::ConvertColor<kPremul_SkAlphaType>(
256         SkPMColor4f color) {
257     return color.unpremul().array();
258 }
259 
260 template<>
261 inline std::array<float, 4> GrSurfaceFillContext::ConvertColor<kUnpremul_SkAlphaType>(
262         SkColor4f color) {
263     return color.premul().array();
264 }
265 
266 template <SkAlphaType AlphaType>
adjustColorAlphaType(SkRGBA4f<AlphaType> color)267 std::array<float, 4> GrSurfaceFillContext::adjustColorAlphaType(SkRGBA4f<AlphaType> color) const {
268     if (AlphaType == kUnknown_SkAlphaType ||
269         this->colorInfo().alphaType() == kUnknown_SkAlphaType) {
270         return color.array();
271     }
272     return (AlphaType == this->colorInfo().alphaType()) ? color.array() : ConvertColor(color);
273 }
274 
275 #endif
276