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