Robert Phillips | f386862 | 2021-08-04 13:27:43 -0400 | [diff] [blame] | 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 | |
Robert Phillips | 53eaa64 | 2021-08-10 13:49:51 -0400 | [diff] [blame^] | 11 | #include "src/gpu/SurfaceContext.h" |
Robert Phillips | f386862 | 2021-08-04 13:27:43 -0400 | [diff] [blame] | 12 | |
| 13 | namespace skgpu { |
| 14 | |
Robert Phillips | 53eaa64 | 2021-08-10 13:49:51 -0400 | [diff] [blame^] | 15 | class SurfaceFillContext : public SurfaceContext { |
Robert Phillips | f386862 | 2021-08-04 13:27:43 -0400 | [diff] [blame] | 16 | public: |
| 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 | |
| 104 | protected: |
| 105 | SurfaceFillContext(GrRecordingContext* rContext, |
Robert Phillips | 53eaa64 | 2021-08-10 13:49:51 -0400 | [diff] [blame^] | 106 | GrSurfaceProxyView readView, |
| 107 | GrSurfaceProxyView writeView, |
| 108 | const GrColorInfo& colorInfo) |
| 109 | : SurfaceContext(rContext, std::move(readView), colorInfo) |
Robert Phillips | f386862 | 2021-08-04 13:27:43 -0400 | [diff] [blame] | 110 | , 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 | |
| 123 | private: |
| 124 | virtual void internalClear(const SkIRect* scissor, |
| 125 | std::array<float, 4> color, |
| 126 | bool upgradePartialToFull = false) = 0; |
| 127 | |
Robert Phillips | 53eaa64 | 2021-08-10 13:49:51 -0400 | [diff] [blame^] | 128 | using INHERITED = SurfaceContext; |
Robert Phillips | f386862 | 2021-08-04 13:27:43 -0400 | [diff] [blame] | 129 | }; |
| 130 | |
| 131 | template<> |
| 132 | inline std::array<float, 4> SurfaceFillContext::ConvertColor<kPremul_SkAlphaType>( |
| 133 | SkPMColor4f color) { |
| 134 | return color.unpremul().array(); |
| 135 | } |
| 136 | |
| 137 | template<> |
| 138 | inline std::array<float, 4> SurfaceFillContext::ConvertColor<kUnpremul_SkAlphaType>( |
| 139 | SkColor4f color) { |
| 140 | return color.premul().array(); |
| 141 | } |
| 142 | |
| 143 | template <SkAlphaType AlphaType> |
| 144 | std::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 |