blob: 65bfca1b032fbcd1fb5475262bd8ff4c32fd46ba [file] [log] [blame]
Robert Phillipsf3868622021-08-04 13:27:43 -04001/*
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
Robert Phillips53eaa642021-08-10 13:49:51 -040011#include "src/gpu/SurfaceContext.h"
Robert Phillipsf3868622021-08-04 13:27:43 -040012
13namespace skgpu {
14
Robert Phillips53eaa642021-08-10 13:49:51 -040015class SurfaceFillContext : public SurfaceContext {
Robert Phillipsf3868622021-08-04 13:27:43 -040016public:
17
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>
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. */
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>
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' */
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' */
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. */
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 */
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
104protected:
105 SurfaceFillContext(GrRecordingContext* rContext,
Robert Phillips53eaa642021-08-10 13:49:51 -0400106 GrSurfaceProxyView readView,
107 GrSurfaceProxyView writeView,
108 const GrColorInfo& colorInfo)
109 : SurfaceContext(rContext, std::move(readView), colorInfo)
Robert Phillipsf3868622021-08-04 13:27:43 -0400110 , 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
123private:
124 virtual void internalClear(const SkIRect* scissor,
125 std::array<float, 4> color,
126 bool upgradePartialToFull = false) = 0;
127
Robert Phillips53eaa642021-08-10 13:49:51 -0400128 using INHERITED = SurfaceContext;
Robert Phillipsf3868622021-08-04 13:27:43 -0400129};
130
131template<>
132inline std::array<float, 4> SurfaceFillContext::ConvertColor<kPremul_SkAlphaType>(
133 SkPMColor4f color) {
134 return color.unpremul().array();
135}
136
137template<>
138inline std::array<float, 4> SurfaceFillContext::ConvertColor<kUnpremul_SkAlphaType>(
139 SkColor4f color) {
140 return color.premul().array();
141}
142
143template <SkAlphaType AlphaType>
144std::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