Add a makeDrawContextWithFallback that handles config fallback

This fixes a bug in find_or_create_rrect_blur_mask where an A8-based drawContext was desired but creation was failing b.c. A8 wasn't renderable.

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2296193005

Review-Url: https://codereview.chromium.org/2296193005
This commit is contained in:
robertphillips 2016-09-06 05:20:20 -07:00 committed by Commit bot
parent 712bb1ecde
commit 48fde9c412
9 changed files with 125 additions and 86 deletions

View File

@ -194,6 +194,22 @@ public:
const SkSurfaceProps* surfaceProps = nullptr,
SkBudgeted = SkBudgeted::kYes);
/*
* This method will attempt to create a drawContext that has, at least, the number of
* channels and precision per channel as requested in 'config' (e.g., A8 and 888 can be
* converted to 8888). It may also swizzle the channels (e.g., BGRA -> RGBA).
* SRGB-ness will be preserved.
*/
sk_sp<GrDrawContext> makeDrawContextWithFallback(
SkBackingFit fit,
int width, int height,
GrPixelConfig config,
sk_sp<SkColorSpace> colorSpace,
int sampleCnt = 0,
GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin,
const SkSurfaceProps* surfaceProps = nullptr,
SkBudgeted budgeted = SkBudgeted::kYes);
///////////////////////////////////////////////////////////////////////////
// Misc.

View File

@ -96,16 +96,12 @@ SkAlphaThresholdFilterImpl::SkAlphaThresholdFilterImpl(const SkRegion& region,
sk_sp<GrTexture> SkAlphaThresholdFilterImpl::createMaskTexture(GrContext* context,
const SkMatrix& inMatrix,
const SkIRect& bounds) const {
GrPixelConfig config;
if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
config = kAlpha_8_GrPixelConfig;
} else {
config = kRGBA_8888_GrPixelConfig;
}
sk_sp<GrDrawContext> drawContext(context->makeDrawContext(SkBackingFit::kApprox,
bounds.width(), bounds.height(),
config, nullptr));
sk_sp<GrDrawContext> drawContext(context->makeDrawContextWithFallback(SkBackingFit::kApprox,
bounds.width(),
bounds.height(),
kAlpha_8_GrPixelConfig,
nullptr));
if (!drawContext) {
return nullptr;
}

View File

@ -1121,9 +1121,10 @@ static sk_sp<GrTexture> find_or_create_rrect_blur_mask(GrContext* context,
sk_sp<GrTexture> mask(context->textureProvider()->findAndRefTextureByUniqueKey(key));
if (!mask) {
// TODO: this could be approx but the texture coords will need to be updated
sk_sp<GrDrawContext> dc(context->makeDrawContext(SkBackingFit::kExact,
size.fWidth, size.fHeight,
kAlpha_8_GrPixelConfig, nullptr));
sk_sp<GrDrawContext> dc(context->makeDrawContextWithFallback(SkBackingFit::kExact,
size.fWidth, size.fHeight,
kAlpha_8_GrPixelConfig,
nullptr));
if (!dc) {
return nullptr;
}

View File

@ -104,19 +104,12 @@ static sk_sp<GrTexture> create_mask_GPU(GrContext* context,
sampleCnt = 0;
}
// We actually only need A8, but it often isn't supported as a
// render target so default to RGBA_8888
GrPixelConfig config = kRGBA_8888_GrPixelConfig;
if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, sampleCnt > 0)) {
config = kAlpha_8_GrPixelConfig;
}
sk_sp<GrDrawContext> drawContext(context->makeDrawContext(SkBackingFit::kApprox,
maskRect.width(),
maskRect.height(),
config,
nullptr,
sampleCnt));
sk_sp<GrDrawContext> drawContext(context->makeDrawContextWithFallback(SkBackingFit::kApprox,
maskRect.width(),
maskRect.height(),
kAlpha_8_GrPixelConfig,
nullptr,
sampleCnt));
if (!drawContext) {
return nullptr;
}

View File

@ -407,16 +407,11 @@ sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context,
return sk_sp<GrTexture>(texture);
}
// There's no texture in the cache. Let's try to allocate it then.
GrPixelConfig config = kRGBA_8888_GrPixelConfig;
if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
config = kAlpha_8_GrPixelConfig;
}
sk_sp<GrDrawContext> dc(context->makeDrawContext(SkBackingFit::kApprox,
reducedClip.width(),
reducedClip.height(),
config, nullptr));
sk_sp<GrDrawContext> dc(context->makeDrawContextWithFallback(SkBackingFit::kApprox,
reducedClip.width(),
reducedClip.height(),
kAlpha_8_GrPixelConfig,
nullptr));
if (!dc) {
return nullptr;
}

View File

@ -681,6 +681,62 @@ sk_sp<GrDrawContext> GrContextPriv::makeBackendTextureAsRenderTargetDrawContext(
surfaceProps);
}
static inline GrPixelConfig GrPixelConfigFallback(GrPixelConfig config) {
static const GrPixelConfig kFallback[] = {
kUnknown_GrPixelConfig, // kUnknown_GrPixelConfig
kRGBA_8888_GrPixelConfig, // kAlpha_8_GrPixelConfig
kUnknown_GrPixelConfig, // kIndex_8_GrPixelConfig
kRGBA_8888_GrPixelConfig, // kRGB_565_GrPixelConfig
kRGBA_8888_GrPixelConfig, // kRGBA_4444_GrPixelConfig
kUnknown_GrPixelConfig, // kRGBA_8888_GrPixelConfig
kRGBA_8888_GrPixelConfig, // kBGRA_8888_GrPixelConfig
kUnknown_GrPixelConfig, // kSRGBA_8888_GrPixelConfig
kSRGBA_8888_GrPixelConfig, // kSBGRA_8888_GrPixelConfig
kUnknown_GrPixelConfig, // kETC1_GrPixelConfig
kUnknown_GrPixelConfig, // kLATC_GrPixelConfig
kUnknown_GrPixelConfig, // kR11_EAC_GrPixelConfig
kUnknown_GrPixelConfig, // kASTC_12x12_GrPixelConfig
kUnknown_GrPixelConfig, // kRGBA_float_GrPixelConfig
kRGBA_half_GrPixelConfig, // kAlpha_half_GrPixelConfig
kUnknown_GrPixelConfig, // kRGBA_half_GrPixelConfig
};
return kFallback[config];
GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig);
GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig);
GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig);
GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig);
GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig);
GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig);
GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig);
GR_STATIC_ASSERT(7 == kSRGBA_8888_GrPixelConfig);
GR_STATIC_ASSERT(8 == kSBGRA_8888_GrPixelConfig);
GR_STATIC_ASSERT(9 == kETC1_GrPixelConfig);
GR_STATIC_ASSERT(10 == kLATC_GrPixelConfig);
GR_STATIC_ASSERT(11 == kR11_EAC_GrPixelConfig);
GR_STATIC_ASSERT(12 == kASTC_12x12_GrPixelConfig);
GR_STATIC_ASSERT(13 == kRGBA_float_GrPixelConfig);
GR_STATIC_ASSERT(14 == kAlpha_half_GrPixelConfig);
GR_STATIC_ASSERT(15 == kRGBA_half_GrPixelConfig);
GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFallback) == kGrPixelConfigCnt);
}
sk_sp<GrDrawContext> GrContext::makeDrawContextWithFallback(SkBackingFit fit,
int width, int height,
GrPixelConfig config,
sk_sp<SkColorSpace> colorSpace,
int sampleCnt,
GrSurfaceOrigin origin,
const SkSurfaceProps* surfaceProps,
SkBudgeted budgeted) {
if (!this->caps()->isConfigRenderable(config, sampleCnt > 0)) {
config = GrPixelConfigFallback(config);
}
return this->makeDrawContext(fit, width, height, config, std::move(colorSpace),
sampleCnt, origin, surfaceProps, budgeted);
}
sk_sp<GrDrawContext> GrContext::makeDrawContext(SkBackingFit fit,
int width, int height,
GrPixelConfig config,
@ -689,6 +745,10 @@ sk_sp<GrDrawContext> GrContext::makeDrawContext(SkBackingFit fit,
GrSurfaceOrigin origin,
const SkSurfaceProps* surfaceProps,
SkBudgeted budgeted) {
if (!this->caps()->isConfigRenderable(config, sampleCnt > 0)) {
return nullptr;
}
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fOrigin = origin;

View File

@ -33,35 +33,13 @@ static GrTexture* copy_on_gpu(GrTexture* inputTexture, const SkIRect* subset,
SkASSERT(!subset || !subset->isEmpty());
GrContext* context = inputTexture->getContext();
SkASSERT(context);
const GrCaps* caps = context->caps();
GrPixelConfig config = GrMakePixelConfigUncompressed(inputTexture->config());
// If the config isn't renderable try converting to either A8 or an 32 bit config. Otherwise,
// fail.
if (!caps->isConfigRenderable(config, false)) {
if (GrPixelConfigIsAlphaOnly(config)) {
if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
config = kAlpha_8_GrPixelConfig;
} else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
config = kSkia8888_GrPixelConfig;
} else {
return nullptr;
}
} else if (kRGB_GrColorComponentFlags ==
(kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(config))) {
if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
config = kSkia8888_GrPixelConfig;
} else {
return nullptr;
}
} else {
return nullptr;
}
}
sk_sp<GrDrawContext> copyDC = context->makeDrawContext(SkBackingFit::kExact, copyParams.fWidth,
copyParams.fHeight, config, nullptr);
sk_sp<GrDrawContext> copyDC = context->makeDrawContextWithFallback(SkBackingFit::kExact,
copyParams.fWidth,
copyParams.fHeight,
config, nullptr);
if (!copyDC) {
return nullptr;
}

View File

@ -58,45 +58,48 @@ bool GrTextureToYUVPlanes(GrTexture* texture, const SkISize sizes[3], void* cons
sk_sp<GrDrawContext> uDrawContext;
sk_sp<GrDrawContext> vDrawContext;
GrPixelConfig singleChannelPixelConfig;
if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
singleChannelPixelConfig = kAlpha_8_GrPixelConfig;
} else {
singleChannelPixelConfig = kRGBA_8888_GrPixelConfig;
}
// We issue draw(s) to convert from RGBA to Y, U, and V. All three planes may have different
// sizes however we optimize for two other cases - all planes are the same (1 draw to YUV),
// and U and V are the same but Y differs (2 draws, one for Y, one for UV).
if (sizes[0] == sizes[1] && sizes[1] == sizes[2]) {
yuvDrawContext = context->makeDrawContext(SkBackingFit::kApprox,
sizes[0].fWidth, sizes[0].fHeight,
kRGBA_8888_GrPixelConfig, nullptr);
yuvDrawContext = context->makeDrawContextWithFallback(SkBackingFit::kApprox,
sizes[0].fWidth,
sizes[0].fHeight,
kRGBA_8888_GrPixelConfig,
nullptr);
if (!yuvDrawContext) {
return false;
}
} else {
yDrawContext = context->makeDrawContext(SkBackingFit::kApprox,
sizes[0].fWidth, sizes[0].fHeight,
singleChannelPixelConfig, nullptr);
yDrawContext = context->makeDrawContextWithFallback(SkBackingFit::kApprox,
sizes[0].fWidth,
sizes[0].fHeight,
kAlpha_8_GrPixelConfig,
nullptr);
if (!yDrawContext) {
return false;
}
if (sizes[1] == sizes[2]) {
// TODO: Add support for GL_RG when available.
uvDrawContext = context->makeDrawContext(SkBackingFit::kApprox,
sizes[1].fWidth, sizes[1].fHeight,
kRGBA_8888_GrPixelConfig, nullptr);
uvDrawContext = context->makeDrawContextWithFallback(SkBackingFit::kApprox,
sizes[1].fWidth,
sizes[1].fHeight,
kRGBA_8888_GrPixelConfig,
nullptr);
if (!uvDrawContext) {
return false;
}
} else {
uDrawContext = context->makeDrawContext(SkBackingFit::kApprox,
sizes[1].fWidth, sizes[1].fHeight,
singleChannelPixelConfig, nullptr);
vDrawContext = context->makeDrawContext(SkBackingFit::kApprox,
sizes[2].fWidth, sizes[2].fHeight,
singleChannelPixelConfig, nullptr);
uDrawContext = context->makeDrawContextWithFallback(SkBackingFit::kApprox,
sizes[1].fWidth,
sizes[1].fHeight,
kAlpha_8_GrPixelConfig,
nullptr);
vDrawContext = context->makeDrawContextWithFallback(SkBackingFit::kApprox,
sizes[2].fWidth,
sizes[2].fHeight,
kAlpha_8_GrPixelConfig,
nullptr);
if (!uDrawContext || !vDrawContext) {
return false;
}

View File

@ -172,9 +172,6 @@ sk_sp<GrDrawContext> SkGpuDevice::MakeDrawContext(GrContext* context,
}
GrPixelConfig config = SkImageInfo2GrPixelConfig(ct, at, cs, *context->caps());
if (!context->caps()->isConfigRenderable(config, sampleCount > 0)) {
return nullptr;
}
return context->makeDrawContext(SkBackingFit::kExact, // Why exact?
origInfo.width(), origInfo.height(),