Fix some GPU image filter code to preserve precision and color space
On the pure-GPU path, we just have an SkSpecialImage (that's definitely texture backed), and we need a renderable config for the draw context we make. Added a helper function to pick - this is basically the high precision analog of what we were doing before (always using 8888). The assert that I added catches many other problems in image filter code, but those fixes are coming in subsequent CLs. 12 GMs render correctly (or more correctly) in gpusrgb and gpuf16 configs. In most cases, they were drawing previously nothing. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2359443003 Review-Url: https://codereview.chromium.org/2359443003
This commit is contained in:
parent
4d450d24f5
commit
2695eaa41f
@ -22,6 +22,7 @@
|
||||
#include "GrContext.h"
|
||||
#include "GrDrawContext.h"
|
||||
#include "GrFixedClip.h"
|
||||
#include "SkGrPriv.h"
|
||||
#endif
|
||||
|
||||
#ifndef SK_IGNORE_TO_STRING
|
||||
@ -282,9 +283,10 @@ sk_sp<SkSpecialImage> SkImageFilter::DrawWithFP(GrContext* context,
|
||||
paint.addColorFragmentProcessor(std::move(fp));
|
||||
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
||||
|
||||
GrPixelConfig config = GrRenderableConfigForColorSpace(colorSpace.get());
|
||||
sk_sp<GrDrawContext> drawContext(context->makeDrawContext(SkBackingFit::kApprox,
|
||||
bounds.width(), bounds.height(),
|
||||
kRGBA_8888_GrPixelConfig,
|
||||
config,
|
||||
std::move(colorSpace)));
|
||||
if (!drawContext) {
|
||||
return nullptr;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "GrCoordTransform.h"
|
||||
#include "GrInvariantOutput.h"
|
||||
#include "SkGr.h"
|
||||
#include "SkGrPriv.h"
|
||||
#include "effects/GrTextureDomain.h"
|
||||
#include "glsl/GrGLSLFragmentProcessor.h"
|
||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
@ -337,7 +338,8 @@ sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* sou
|
||||
|
||||
sk_sp<GrDrawContext> drawContext(
|
||||
context->makeDrawContext(SkBackingFit::kApprox, bounds.width(), bounds.height(),
|
||||
kSkia8888_GrPixelConfig, sk_ref_sp(source->getColorSpace())));
|
||||
GrRenderableConfigForColorSpace(source->getColorSpace()),
|
||||
sk_ref_sp(source->getColorSpace())));
|
||||
if (!drawContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "GrInvariantOutput.h"
|
||||
#include "GrPaint.h"
|
||||
#include "SkGr.h"
|
||||
#include "SkGrPriv.h"
|
||||
#include "effects/GrSingleTextureEffect.h"
|
||||
#include "effects/GrTextureDomain.h"
|
||||
#include "glsl/GrGLSLFragmentProcessor.h"
|
||||
@ -409,11 +410,10 @@ sk_sp<SkSpecialImage> SkLightingImageFilterInternal::filterImageGPU(SkSpecialIma
|
||||
sk_sp<GrTexture> inputTexture(input->asTextureRef(context));
|
||||
SkASSERT(inputTexture);
|
||||
|
||||
sk_sp<GrDrawContext> drawContext(context->makeDrawContext(SkBackingFit::kApprox,
|
||||
offsetBounds.width(),
|
||||
offsetBounds.height(),
|
||||
kRGBA_8888_GrPixelConfig,
|
||||
sk_ref_sp(source->getColorSpace())));
|
||||
sk_sp<GrDrawContext> drawContext(
|
||||
context->makeDrawContext(SkBackingFit::kApprox,offsetBounds.width(), offsetBounds.height(),
|
||||
GrRenderableConfigForColorSpace(source->getColorSpace()),
|
||||
sk_ref_sp(source->getColorSpace())));
|
||||
if (!drawContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "GrInvariantOutput.h"
|
||||
#include "GrTexture.h"
|
||||
#include "SkGr.h"
|
||||
#include "SkGrPriv.h"
|
||||
#include "effects/Gr1DKernelEffect.h"
|
||||
#include "glsl/GrGLSLFragmentProcessor.h"
|
||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
@ -476,6 +477,7 @@ static sk_sp<SkSpecialImage> apply_morphology(GrContext* context,
|
||||
sk_sp<GrTexture> srcTexture(input->asTextureRef(context));
|
||||
SkASSERT(srcTexture);
|
||||
sk_sp<SkColorSpace> colorSpace = sk_ref_sp(input->getColorSpace());
|
||||
GrPixelConfig config = GrRenderableConfigForColorSpace(colorSpace.get());
|
||||
|
||||
// setup new clip
|
||||
const GrFixedClip clip(SkIRect::MakeWH(srcTexture->width(), srcTexture->height()));
|
||||
@ -488,8 +490,7 @@ static sk_sp<SkSpecialImage> apply_morphology(GrContext* context,
|
||||
if (radius.fWidth > 0) {
|
||||
sk_sp<GrDrawContext> dstDrawContext(context->makeDrawContext(SkBackingFit::kApprox,
|
||||
rect.width(), rect.height(),
|
||||
kSkia8888_GrPixelConfig,
|
||||
colorSpace));
|
||||
config, colorSpace));
|
||||
if (!dstDrawContext) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -510,8 +511,7 @@ static sk_sp<SkSpecialImage> apply_morphology(GrContext* context,
|
||||
if (radius.fHeight > 0) {
|
||||
sk_sp<GrDrawContext> dstDrawContext(context->makeDrawContext(SkBackingFit::kApprox,
|
||||
rect.width(), rect.height(),
|
||||
kSkia8888_GrPixelConfig,
|
||||
colorSpace));
|
||||
config, colorSpace));
|
||||
if (!dstDrawContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "effects/GrTextureDomain.h"
|
||||
#include "effects/GrSimpleTextureEffect.h"
|
||||
#include "SkGr.h"
|
||||
#include "SkGrPriv.h"
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -240,10 +241,10 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter::filterImageGPU(SkSpecialImage* sour
|
||||
|
||||
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
||||
|
||||
sk_sp<GrDrawContext> drawContext(context->makeDrawContext(SkBackingFit::kApprox,
|
||||
bounds.width(), bounds.height(),
|
||||
kSkia8888_GrPixelConfig,
|
||||
sk_ref_sp(source->getColorSpace())));
|
||||
sk_sp<GrDrawContext> drawContext(
|
||||
context->makeDrawContext(SkBackingFit::kApprox, bounds.width(), bounds.height(),
|
||||
GrRenderableConfigForColorSpace(source->getColorSpace()),
|
||||
sk_ref_sp(source->getColorSpace())));
|
||||
if (!drawContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -222,6 +222,8 @@ sk_sp<GrDrawContext> GrDrawingManager::makeDrawContext(sk_sp<GrRenderTarget> rt,
|
||||
// by, including internal usage. We allow a null color space here, for read/write pixels and
|
||||
// other special code paths. If a color space is provided, though, enforce all other rules.
|
||||
if (colorSpace && !SkSurface_Gpu::Valid(fContext, rt->config(), colorSpace.get())) {
|
||||
// SRGBTODO: Enable this assert once image filters are propagating color type and space
|
||||
// SkDEBUGFAIL("Invalid config and colorspace combination");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -508,6 +508,19 @@ bool GrPixelConfigToColorType(GrPixelConfig config, SkColorType* ctOut) {
|
||||
return true;
|
||||
}
|
||||
|
||||
GrPixelConfig GrRenderableConfigForColorSpace(SkColorSpace* colorSpace) {
|
||||
if (!colorSpace) {
|
||||
return kRGBA_8888_GrPixelConfig;
|
||||
} else if (colorSpace->gammaIsLinear()) {
|
||||
return kRGBA_half_GrPixelConfig;
|
||||
} else if (colorSpace->gammaCloseToSRGB()) {
|
||||
return kSRGBA_8888_GrPixelConfig;
|
||||
} else {
|
||||
SkDEBUGFAIL("No renderable config exists for color space with strange gamma");
|
||||
return kUnknown_GrPixelConfig;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline bool blend_requires_shader(const SkXfermode::Mode mode, bool primitiveIsSrc) {
|
||||
|
@ -105,6 +105,11 @@ GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo&, const GrCaps&);
|
||||
|
||||
bool GrPixelConfigToColorType(GrPixelConfig, SkColorType*);
|
||||
|
||||
/** When image filter code needs to construct a draw context to do intermediate rendering, we need
|
||||
a renderable pixel config. The source (SkSpecialImage) may not be in a renderable format, but
|
||||
we want to preserve the color space of that source. This picks an appropriate format to use. */
|
||||
GrPixelConfig GrRenderableConfigForColorSpace(SkColorSpace*);
|
||||
|
||||
/**
|
||||
* If the compressed data in the SkData is supported (as a texture format, this returns
|
||||
* the pixel-config that should be used, and sets outStartOfDataToUpload to the ptr into
|
||||
|
Loading…
Reference in New Issue
Block a user