Make GrRenderTargetContext async read functions use GrRTC's alpha type.

This shouldn't have any practical effect since GrRTC can't be unpremul
but removes assumptions in these functions. This code will eventually
be lifted up to GrSurfaceContext which can be unpremul.

Change-Id: If8b2fb8b19d1160bc6561f6536518563f57c4351
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/225185
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2019-07-02 15:10:58 -04:00 committed by Skia Commit-Bot
parent b5f95cd1f8
commit 4d03689edb

View File

@ -1652,10 +1652,8 @@ sk_sp<GrRenderTargetContext> GrRenderTargetContext::rescale(const SkImageInfo& i
return nullptr;
}
// We currently don't know our own alpha type, we assume it's premul if we have an alpha channel
// and opaque otherwise.
if (!GrPixelConfigIsAlphaOnly(fRenderTargetProxy->config()) &&
info.alphaType() != kPremul_SkAlphaType) {
// We rescale by drawing and don't currently support drawing to a kUnpremul destination.
if (info.alphaType() == kUnpremul_SkAlphaType) {
return nullptr;
}
@ -1692,17 +1690,17 @@ sk_sp<GrRenderTargetContext> GrRenderTargetContext::rescale(const SkImageInfo& i
stepsY = sy != 1.f;
}
SkASSERT(stepsX || stepsY);
auto rescaleColorSapce = this->colorSpaceInfo().refColorSpace();
auto currRTC = sk_ref_sp(this);
// Assume we should ignore the rescale linear request if the surface has no color space since
// it's unclear how we'd linearize from an unknown color space.
if (rescaleGamma == SkSurface::RescaleGamma::kLinear &&
rescaleColorSapce.get() && !rescaleColorSapce->gammaIsLinear()) {
auto cs = rescaleColorSapce->makeLinearGamma();
if (rescaleGamma == SkSurface::RescaleGamma::kLinear && this->colorSpaceInfo().colorSpace() &&
!this->colorSpaceInfo().colorSpace()->gammaIsLinear()) {
auto cs = this->colorSpaceInfo().colorSpace()->makeLinearGamma();
auto backendFormat = this->caps()->getBackendFormatFromGrColorType(GrColorType::kRGBA_F16,
GrSRGBEncoded::kNo);
auto xform = GrColorSpaceXform::Make(rescaleColorSapce.get(), kPremul_SkAlphaType, cs.get(),
kPremul_SkAlphaType);
auto xform = GrColorSpaceXform::Make(this->colorSpaceInfo().colorSpace(),
this->colorSpaceInfo().alphaType(),
cs.get(), kPremul_SkAlphaType);
// We'll fall back to kRGBA_8888 if half float not supported.
auto linearRTC = fContext->priv().makeDeferredRenderTargetContextWithFallback(
backendFormat, SkBackingFit::kExact, srcW, srcH, kRGBA_half_GrPixelConfig,
@ -1717,7 +1715,6 @@ sk_sp<GrRenderTargetContext> GrRenderTargetContext::rescale(const SkImageInfo& i
std::move(xform));
texProxy = linearRTC->asTextureProxyRef();
currRTC = std::move(linearRTC);
rescaleColorSapce = std::move(cs);
srcX = 0;
srcY = 0;
constraint = SkCanvas::kFast_SrcRectConstraint;
@ -1746,16 +1743,18 @@ sk_sp<GrRenderTargetContext> GrRenderTargetContext::rescale(const SkImageInfo& i
GrBackendFormat backendFormat = texProxy->backendFormat().makeTexture2D();
GrPixelConfig config = texProxy->config();
GrColorType colorType = currRTC->colorSpaceInfo().colorType();
auto cs = rescaleColorSapce;
auto cs = currRTC->colorSpaceInfo().refColorSpace();
sk_sp<GrColorSpaceXform> xform;
auto prevAlphaType = currRTC->colorSpaceInfo().alphaType();
if (!stepsX && !stepsY) {
// Might as well fold conversion to final info in the last step.
backendFormat = this->caps()->getBackendFormatFromColorType(info.colorType());
config = this->caps()->getConfigFromBackendFormat(backendFormat, info.colorType());
cs = info.refColorSpace();
colorType = SkColorTypeToGrColorType(info.colorType());
xform = GrColorSpaceXform::Make(rescaleColorSapce.get(),
kPremul_SkAlphaType, cs.get(), info.alphaType());
xform = GrColorSpaceXform::Make(currRTC->colorSpaceInfo().colorSpace(),
currRTC->colorSpaceInfo().alphaType(),
cs.get(), info.alphaType());
}
currRTC = fContext->priv().makeDeferredRenderTargetContextWithFallback(
backendFormat, SkBackingFit::kExact, nextW, nextH, config, colorType, std::move(cs),
@ -1777,9 +1776,9 @@ sk_sp<GrRenderTargetContext> GrRenderTargetContext::rescale(const SkImageInfo& i
if (srcW != texProxy->width() || srcH != texProxy->height()) {
auto domain = GrTextureDomain::MakeTexelDomain(
SkIRect::MakeXYWH(srcX, srcY, srcW, srcH), GrTextureDomain::kClamp_Mode);
fp = GrBicubicEffect::Make(texProxy, matrix, domain, dir, kPremul_SkAlphaType);
fp = GrBicubicEffect::Make(texProxy, matrix, domain, dir, prevAlphaType);
} else {
fp = GrBicubicEffect::Make(texProxy, matrix, dir, kPremul_SkAlphaType);
fp = GrBicubicEffect::Make(texProxy, matrix, dir, prevAlphaType);
}
if (xform) {
fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(xform));
@ -1819,13 +1818,6 @@ void GrRenderTargetContext::asyncRescaleAndReadPixels(
callback(context, nullptr, 0);
return;
}
// We currently don't know our own alpha type, we assume it's premul if we have an alpha channel
// and opaque otherwise.
if (!GrPixelConfigIsAlphaOnly(fRenderTargetProxy->config()) &&
info.alphaType() != kPremul_SkAlphaType) {
callback(context, nullptr, 0);
return;
}
auto dstCT = SkColorTypeToGrColorType(info.colorType());
bool needsRescale = srcRect.width() != info.width() || srcRect.height() != info.height();
GrPixelConfig configOfFinalContext = fRenderTargetProxy->config();
@ -1866,10 +1858,17 @@ void GrRenderTargetContext::asyncRescaleAndReadPixels(
x = y = 0;
} else {
sk_sp<GrColorSpaceXform> xform =
GrColorSpaceXform::Make(this->colorSpaceInfo().colorSpace(), kPremul_SkAlphaType,
GrColorSpaceXform::Make(this->colorSpaceInfo().colorSpace(),
this->colorSpaceInfo().alphaType(),
info.colorSpace(), info.alphaType());
// Insert a draw to a temporary surface if we need to do a y-flip or color space conversion.
if (this->origin() == kBottomLeft_GrSurfaceOrigin || xform) {
// We flip or color convert by drawing and we don't currently support drawing to
// kPremul.
if (info.alphaType() == kUnpremul_SkAlphaType) {
callback(context, nullptr, 0);
return;
}
sk_sp<GrTextureProxy> texProxy = sk_ref_sp(fRenderTargetProxy->asTextureProxy());
const auto backendFormat = fRenderTargetProxy->backendFormat().makeTexture2D();
SkRect srcRectToDraw = SkRect::Make(srcRect);
@ -1953,6 +1952,8 @@ GrRenderTargetContext::PixelTransferResult GrRenderTargetContext::transferPixels
if (supportedRead.fColorType != dstCT || supportedRead.fSwizzle != GrSwizzle("rgba") || flip) {
result.fPixelConverter = [w = rect.width(), h = rect.height(), dstCT, supportedRead](
void* dst, const void* src) {
// We're using kPremul here for src and dst simply because we don't want any alpha type
// conversions.
GrPixelInfo srcInfo(supportedRead.fColorType, kPremul_SkAlphaType, nullptr, w, h);
GrPixelInfo dstInfo(dstCT, kPremul_SkAlphaType, nullptr, w, h);
GrConvertPixels(dstInfo, dst, dstInfo.minRowBytes(),
@ -1973,7 +1974,8 @@ void GrRenderTargetContext::asyncReadPixels(const SkIRect& rect, SkColorType col
if (!transferResult.fTransferBuffer) {
SkAutoPixmapStorage pm;
auto ii = SkImageInfo::Make(rect.width(), rect.height(), colorType, kPremul_SkAlphaType,
auto ii = SkImageInfo::Make(rect.width(), rect.height(), colorType,
this->colorSpaceInfo().alphaType(),
this->colorSpaceInfo().refColorSpace());
pm.alloc(ii);
if (!this->readPixels(ii, pm.writable_addr(), pm.rowBytes(), {rect.fLeft, rect.fTop})) {
@ -2003,15 +2005,14 @@ void GrRenderTargetContext::asyncReadPixels(const SkIRect& rect, SkColorType col
delete context;
return;
}
SkAutoPixmapStorage pm;
std::unique_ptr<char[]> tmp;
size_t rowBytes = context->fW * SkColorTypeBytesPerPixel(context->fColorType);
if (context->fTransferResult.fPixelConverter) {
pm.alloc(SkImageInfo::Make(context->fW, context->fH, context->fColorType,
kPremul_SkAlphaType, nullptr));
context->fTransferResult.fPixelConverter(pm.writable_addr(), data);
data = pm.addr();
tmp.reset(new char[rowBytes * context->fH]);
context->fTransferResult.fPixelConverter(tmp.get(), data);
data = tmp.get();
}
(*context->fClientCallback)(context->fClientContext, data,
context->fW * SkColorTypeBytesPerPixel(context->fColorType));
(*context->fClientCallback)(context->fClientContext, data, rowBytes);
delete context;
};
GrFlushInfo flushInfo;
@ -2044,6 +2045,7 @@ void GrRenderTargetContext::asyncRescaleAndReadPixelsYUV420(
auto rtc = sk_ref_sp(this);
bool needsRescale = srcRect.width() != dstW || srcRect.height() != dstH;
if (needsRescale) {
// We assume the caller wants kPremul. There is no way to indicate a preference.
auto info = SkImageInfo::Make(dstW, dstH, kRGBA_8888_SkColorType, kPremul_SkAlphaType,
dstColorSpace);
// TODO: Incorporate the YUV conversion into last pass of rescaling.
@ -2056,9 +2058,10 @@ void GrRenderTargetContext::asyncRescaleAndReadPixelsYUV420(
SkASSERT(rtc->origin() == kTopLeft_GrSurfaceOrigin);
x = y = 0;
} else {
sk_sp<GrColorSpaceXform> xform =
GrColorSpaceXform::Make(this->colorSpaceInfo().colorSpace(), kPremul_SkAlphaType,
dstColorSpace.get(), kPremul_SkAlphaType);
// We assume the caller wants kPremul. There is no way to indicate a preference.
sk_sp<GrColorSpaceXform> xform = GrColorSpaceXform::Make(
this->colorSpaceInfo().colorSpace(), this->colorSpaceInfo().alphaType(),
dstColorSpace.get(), kPremul_SkAlphaType);
if (xform) {
sk_sp<GrTextureProxy> texProxy = this->asTextureProxyRef();
// TODO: Do something if the input is not a texture already.