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:
parent
712bb1ecde
commit
48fde9c412
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(),
|
||||
|
Loading…
Reference in New Issue
Block a user