/* * 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; /** * 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 void clear(const SkIRect& rect, const SkRGBA4f& color) { this->internalClear(&rect, this->adjustColorAlphaType(color)); } /** Clears the entire render target to the color. */ template void clear(const SkRGBA4f& 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 void clearAtLeast(const SkIRect& scissor, const SkRGBA4f& color) { this->internalClear(&scissor, this->adjustColorAlphaType(color), /* upgrade to full */ true); } /** Fills 'dstRect' with 'fp' */ virtual void fillRectWithFP(const SkIRect& dstRect, std::unique_ptr) = 0; /** * A convenience version of fillRectWithFP that applies a coordinate transformation via * GrMatrixEffect. */ void fillRectWithFP(const SkIRect& dstRect, const SkMatrix& localMatrix, std::unique_ptr); /** Fills 'dstRect' with 'fp' using a local matrix that maps 'srcRect' to 'dstRect' */ void fillRectToRectWithFP(const SkRect& srcRect, const SkIRect& dstRect, std::unique_ptr 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 fp) { this->fillRectToRectWithFP(SkRect::Make(srcRect), dstRect, std::move(fp)); } /** Fills the entire render target with the passed FP. */ void fillWithFP(std::unique_ptr 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 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 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 static std::array ConvertColor(SkRGBA4f color); template std::array adjustColorAlphaType(SkRGBA4f color) const; GrSurfaceProxyView fWriteView; private: virtual void internalClear(const SkIRect* scissor, std::array color, bool upgradePartialToFull = false) = 0; using INHERITED = SurfaceContext; }; template<> inline std::array SurfaceFillContext::ConvertColor( SkPMColor4f color) { return color.unpremul().array(); } template<> inline std::array SurfaceFillContext::ConvertColor( SkColor4f color) { return color.premul().array(); } template std::array SurfaceFillContext::adjustColorAlphaType(SkRGBA4f 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