| /* |
| * Copyright 2021 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef SurfaceFillContext_DEFINED |
| #define SurfaceFillContext_DEFINED |
| |
| #include "src/gpu/SurfaceContext.h" |
| |
| namespace skgpu { |
| |
| class SurfaceFillContext : public SurfaceContext { |
| public: |
| |
| SurfaceFillContext* asFillContext() override { return this; } |
| |
| /** |
| * Provides a performance hint that the render target's contents are allowed |
| * to become undefined. |
| */ |
| virtual void discard() = 0; |
| |
| virtual void resolveMSAA() = 0; |
| |
| /** |
| * Clear the rect of the render target to the given color. |
| * @param rect the rect to clear to |
| * @param color the color to clear to. |
| */ |
| template <SkAlphaType AlphaType> |
| void clear(const SkIRect& rect, const SkRGBA4f<AlphaType>& color) { |
| this->internalClear(&rect, this->adjustColorAlphaType(color)); |
| } |
| |
| /** Clears the entire render target to the color. */ |
| template <SkAlphaType AlphaType> void clear(const SkRGBA4f<AlphaType>& color) { |
| this->internalClear(nullptr, this->adjustColorAlphaType(color)); |
| } |
| |
| /** |
| * Clear at minimum the pixels within 'scissor', but is allowed to clear the full render target |
| * if that is the more performant option. |
| */ |
| template <SkAlphaType AlphaType> |
| void clearAtLeast(const SkIRect& scissor, const SkRGBA4f<AlphaType>& color) { |
| this->internalClear(&scissor, |
| this->adjustColorAlphaType(color), |
| /* upgrade to full */ true); |
| } |
| |
| /** Fills 'dstRect' with 'fp' */ |
| virtual void fillRectWithFP(const SkIRect& dstRect, std::unique_ptr<GrFragmentProcessor>) = 0; |
| |
| /** |
| * A convenience version of fillRectWithFP that applies a coordinate transformation via |
| * GrMatrixEffect. |
| */ |
| void fillRectWithFP(const SkIRect& dstRect, |
| const SkMatrix& localMatrix, |
| std::unique_ptr<GrFragmentProcessor>); |
| |
| /** Fills 'dstRect' with 'fp' using a local matrix that maps 'srcRect' to 'dstRect' */ |
| void fillRectToRectWithFP(const SkRect& srcRect, |
| const SkIRect& dstRect, |
| std::unique_ptr<GrFragmentProcessor> fp) { |
| SkMatrix lm = SkMatrix::RectToRect(SkRect::Make(dstRect), srcRect); |
| this->fillRectWithFP(dstRect, lm, std::move(fp)); |
| } |
| |
| /** Fills 'dstRect' with 'fp' using a local matrix that maps 'srcRect' to 'dstRect' */ |
| void fillRectToRectWithFP(const SkIRect& srcRect, |
| const SkIRect& dstRect, |
| std::unique_ptr<GrFragmentProcessor> fp) { |
| this->fillRectToRectWithFP(SkRect::Make(srcRect), dstRect, std::move(fp)); |
| } |
| |
| /** Fills the entire render target with the passed FP. */ |
| void fillWithFP(std::unique_ptr<GrFragmentProcessor> fp) { |
| this->fillRectWithFP(SkIRect::MakeSize(fWriteView.proxy()->dimensions()), std::move(fp)); |
| } |
| |
| /** |
| * A convenience version of fillWithFP that applies a coordinate transformation via |
| * GrMatrixEffect and fills the entire render target. |
| */ |
| void fillWithFP(const SkMatrix& localMatrix, std::unique_ptr<GrFragmentProcessor> fp) { |
| this->fillRectWithFP(SkIRect::MakeSize(fWriteView.proxy()->dimensions()), |
| localMatrix, |
| std::move(fp)); |
| } |
| |
| /** |
| * Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height |
| * of the srcRect. The srcRect and dstRect are clipped to the bounds of the src and dst surfaces |
| * respectively. |
| */ |
| virtual bool blitTexture(GrSurfaceProxyView, |
| const SkIRect& srcRect, |
| const SkIPoint& dstPoint) = 0; |
| |
| virtual sk_sp<GrRenderTask> refRenderTask() = 0; |
| |
| protected: |
| SurfaceFillContext(GrRecordingContext* rContext, |
| GrSurfaceProxyView readView, |
| GrSurfaceProxyView writeView, |
| const GrColorInfo& colorInfo) |
| : SurfaceContext(rContext, std::move(readView), colorInfo) |
| , fWriteView(std::move(writeView)) { |
| SkASSERT(this->asSurfaceProxy() == fWriteView.proxy()); |
| SkASSERT(this->origin() == fWriteView.origin()); |
| } |
| |
| template <SkAlphaType AlphaType> |
| static std::array<float, 4> ConvertColor(SkRGBA4f<AlphaType> color); |
| |
| template <SkAlphaType AlphaType> |
| std::array<float, 4> adjustColorAlphaType(SkRGBA4f<AlphaType> color) const; |
| |
| GrSurfaceProxyView fWriteView; |
| |
| private: |
| virtual void internalClear(const SkIRect* scissor, |
| std::array<float, 4> color, |
| bool upgradePartialToFull = false) = 0; |
| |
| using INHERITED = SurfaceContext; |
| }; |
| |
| template<> |
| inline std::array<float, 4> SurfaceFillContext::ConvertColor<kPremul_SkAlphaType>( |
| SkPMColor4f color) { |
| return color.unpremul().array(); |
| } |
| |
| template<> |
| inline std::array<float, 4> SurfaceFillContext::ConvertColor<kUnpremul_SkAlphaType>( |
| SkColor4f color) { |
| return color.premul().array(); |
| } |
| |
| template <SkAlphaType AlphaType> |
| std::array<float, 4> SurfaceFillContext::adjustColorAlphaType(SkRGBA4f<AlphaType> color) const { |
| if (AlphaType == kUnknown_SkAlphaType || |
| this->colorInfo().alphaType() == kUnknown_SkAlphaType) { |
| return color.array(); |
| } |
| return (AlphaType == this->colorInfo().alphaType()) ? color.array() : ConvertColor(color); |
| } |
| |
| } // namespace skgpu |
| |
| #endif // SurfaceFillContext_DEFINED |