Add GrSurfaceFillContext
This is a new base class for GrSurfaceDrawContext. It allows any
alpha-type but is restricted to non-blending fills of irects using FPs,
clears,and discards.
Bug: skia:11019
Change-Id: I229ce5f452e66796e2fa5c0e7a6ddccbf23bef5c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/341680
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index ab40c07..b9c9444 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -45,8 +45,6 @@
std::unique_ptr<GrSurfaceContext> surfaceContext;
if (proxy->asRenderTargetProxy()) {
- SkASSERT(info.alphaType() == kPremul_SkAlphaType ||
- info.alphaType() == kOpaque_SkAlphaType);
// Will we ever want a swizzle that is not the default write swizzle for the format and
// colorType here? If so we will need to manually pass that in.
GrSwizzle writeSwizzle;
@@ -55,12 +53,19 @@
info.colorType());
}
GrSurfaceProxyView writeView(readView.refProxy(), readView.origin(), writeSwizzle);
- surfaceContext = std::make_unique<GrSurfaceDrawContext>(context,
- std::move(readView),
- std::move(writeView),
- info.colorType(),
- info.refColorSpace(),
- /*surface props*/ nullptr);
+ if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
+ surfaceContext = std::make_unique<GrSurfaceDrawContext>(context,
+ std::move(readView),
+ std::move(writeView),
+ info.colorType(),
+ info.refColorSpace(),
+ /*surface props*/ nullptr);
+ } else {
+ surfaceContext = std::make_unique<GrSurfaceFillContext>(context,
+ std::move(readView),
+ std::move(writeView),
+ info);
+ }
} else {
surfaceContext = std::make_unique<GrSurfaceContext>(context, std::move(readView), info);
}
@@ -237,11 +242,14 @@
GrColorType colorType = (canvas2DFastPath || srcIsCompressed)
? GrColorType::kRGBA_8888
: this->colorInfo().colorType();
- tempCtx = GrSurfaceDrawContext::Make(
- dContext, colorType, this->colorInfo().refColorSpace(), SkBackingFit::kApprox,
- dstInfo.dimensions(), 1, GrMipMapped::kNo, GrProtected::kNo,
- kTopLeft_GrSurfaceOrigin);
- if (!tempCtx) {
+ SkAlphaType alphaType = canvas2DFastPath ? dstInfo.alphaType()
+ : this->colorInfo().alphaType();
+ GrImageInfo tempInfo(colorType,
+ alphaType,
+ this->colorInfo().refColorSpace(),
+ dstInfo.dimensions());
+ auto sfc = GrSurfaceFillContext::Make(dContext, tempInfo, SkBackingFit::kApprox);
+ if (!sfc) {
return false;
}
@@ -253,25 +261,17 @@
fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
dstInfo = dstInfo.makeColorType(GrColorType::kRGBA_8888);
}
- // The render target context is incorrectly tagged as kPremul even though we're
- // writing unpremul data thanks to the PMToUPM effect. Fake out the dst alpha type
- // so we don't double unpremul.
- dstInfo = dstInfo.makeAlphaType(kPremul_SkAlphaType);
} else {
fp = GrTextureEffect::Make(this->readSurfaceView(), this->colorInfo().alphaType());
}
if (!fp) {
return false;
}
- GrPaint paint;
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- paint.setColorFragmentProcessor(std::move(fp));
-
- tempCtx->asRenderTargetContext()->fillRectToRect(
- nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
- SkRect::MakeWH(dstInfo.width(), dstInfo.height()),
- SkRect::MakeXYWH(pt.fX, pt.fY, dstInfo.width(), dstInfo.height()));
+ sfc->fillRectToRectWithFP(SkIRect::MakePtSize(pt, dstInfo.dimensions()),
+ SkIRect::MakeSize(dstInfo.dimensions()),
+ std::move(fp));
pt = {0, 0};
+ tempCtx = std::move(sfc);
} else {
auto restrictions = this->caps()->getDstCopyRestrictions(this->asRenderTargetProxy(),
this->colorInfo().colorType());
@@ -404,7 +404,7 @@
bool canvas2DFastPath = !caps->avoidWritePixelsFastPath() && premul && !needColorConversion &&
(srcInfo.colorType() == GrColorType::kRGBA_8888 ||
srcInfo.colorType() == GrColorType::kBGRA_8888) &&
- SkToBool(this->asRenderTargetContext()) &&
+ this->asFillContext() &&
(dstColorType == GrColorType::kRGBA_8888 ||
dstColorType == GrColorType::kBGRA_8888) &&
rgbaDefaultFormat.isValid() &&
@@ -434,7 +434,7 @@
// we can use a draw instead which doesn't have this origin restriction. Thus for render
// targets we will use top left and otherwise we will make the origins match.
GrSurfaceOrigin tempOrigin =
- this->asRenderTargetContext() ? kTopLeft_GrSurfaceOrigin : this->origin();
+ this->asFillContext() ? kTopLeft_GrSurfaceOrigin : this->origin();
auto tempProxy = dContext->priv().proxyProvider()->createProxy(
format, srcInfo.dimensions(), GrRenderable::kNo, 1, GrMipmapped::kNo,
SkBackingFit::kApprox, SkBudgeted::kYes, GrProtected::kNo);
@@ -455,7 +455,7 @@
return false;
}
- if (this->asRenderTargetContext()) {
+ if (this->asFillContext()) {
std::unique_ptr<GrFragmentProcessor> fp;
if (canvas2DFastPath) {
fp = dContext->priv().createUPMToPMEffect(
@@ -470,13 +470,10 @@
if (!fp) {
return false;
}
- GrPaint paint;
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- paint.setColorFragmentProcessor(std::move(fp));
- this->asRenderTargetContext()->fillRectToRect(
- nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
- SkRect::MakeXYWH(pt.fX, pt.fY, srcInfo.width(), srcInfo.height()),
- SkRect::MakeWH(srcInfo.width(), srcInfo.height()));
+ this->asFillContext()->fillRectToRectWithFP(
+ SkIRect::MakeSize(srcInfo.dimensions()),
+ SkIRect::MakePtSize(pt, srcInfo.dimensions()),
+ std::move(fp));
} else {
SkIRect srcRect = SkIRect::MakeWH(srcInfo.width(), srcInfo.height());
SkIPoint dstPoint = SkIPoint::Make(pt.fX, pt.fY);