blob: c74c048942e0f815a63a669cb1e646288de48f8e [file] [log] [blame]
/*
* 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