aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar brianosman <brianosman@google.com>2016-04-06 07:38:23 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-06 07:38:23 -0700
commit898235c4864df66aa7f6d32bc2a8b8551040ce1e (patch)
tree5fb30f04825c59a970a208cabadd4bad0be283b3
parent1817d282cda17cb8c2db0ac6fdc937743c026016 (diff)
SkSurfaceProps now has a gamma-correct ("AllowSRGBInputs") flag. That's propagated in a few places so that the backend can do the right thing for L32 vs S32 mode.
Also added SkSurfaceProps to SkSpecialImage, so that Image -> Surface conversion can preserve the desired behavior during filtering. Many small changes, including a bunch of comments about places where we may be losing information right now. My approach was to ensure that if anything fails, it will always fall back to "legacy" mode - gamma-correctness is opt-in, so I'll just have to feed things through as missing cases are exposed. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1838953007 Review URL: https://codereview.chromium.org/1845283003
-rw-r--r--dm/DM.cpp7
-rw-r--r--dm/DMGpuSupport.h3
-rw-r--r--gm/constcolorprocessor.cpp3
-rw-r--r--gm/dftext.cpp8
-rw-r--r--gm/surface.cpp13
-rw-r--r--gm/textblobgeometrychange.cpp7
-rw-r--r--gm/textblobmixedsizes.cpp8
-rw-r--r--gm/textblobrandomfont.cpp8
-rw-r--r--gm/xfermodes3.cpp4
-rw-r--r--include/core/SkCanvas.h7
-rw-r--r--include/core/SkDevice.h11
-rw-r--r--include/core/SkImageInfo.h10
-rw-r--r--include/core/SkSurfaceProps.h12
-rw-r--r--include/gpu/GrDrawContext.h1
-rw-r--r--include/gpu/GrPaint.h9
-rw-r--r--include/gpu/GrTypes.h10
-rw-r--r--src/core/SkCanvas.cpp15
-rw-r--r--src/core/SkDevice.cpp3
-rw-r--r--src/core/SkImageFilter.cpp9
-rw-r--r--src/core/SkSpecialImage.cpp74
-rw-r--r--src/core/SkSpecialImage.h29
-rw-r--r--src/core/SkSpecialSurface.cpp6
-rw-r--r--src/effects/SkBlurImageFilter.cpp5
-rw-r--r--src/effects/SkBlurMaskFilter.cpp3
-rw-r--r--src/effects/SkDisplacementMapEffect.cpp1
-rw-r--r--src/effects/SkGpuBlurUtils.cpp14
-rw-r--r--src/effects/SkGpuBlurUtils.h2
-rw-r--r--src/effects/SkImageSource.cpp4
-rw-r--r--src/effects/SkLightingImageFilter.cpp1
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp6
-rw-r--r--src/effects/SkXfermodeImageFilter.cpp1
-rw-r--r--src/gpu/GrBlurUtils.cpp3
-rw-r--r--src/gpu/GrContext.cpp4
-rw-r--r--src/gpu/GrLayerHoister.cpp3
-rw-r--r--src/gpu/GrPaint.cpp1
-rw-r--r--src/gpu/GrPipeline.cpp3
-rw-r--r--src/gpu/GrPipeline.h4
-rw-r--r--src/gpu/GrPipelineBuilder.cpp2
-rw-r--r--src/gpu/GrPipelineBuilder.h9
-rw-r--r--src/gpu/SkGpuDevice.cpp60
-rw-r--r--src/gpu/SkGpuDevice_drawTexture.cpp2
-rw-r--r--src/gpu/SkGr.cpp19
-rw-r--r--src/gpu/SkGrPriv.h9
-rw-r--r--src/gpu/gl/GrGLGpu.cpp6
-rw-r--r--src/gpu/text/GrAtlasTextContext.cpp5
-rw-r--r--src/gpu/text/GrStencilAndCoverTextContext.cpp4
-rw-r--r--src/views/SkWindow.cpp11
-rw-r--r--tools/gpu/GrTest.cpp3
48 files changed, 315 insertions, 127 deletions
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 4a81cee9e1..9611f493f1 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -822,8 +822,8 @@ static Sink* create_sink(const SkCommandLineConfig* config) {
contextOptions = static_cast<GrContextFactory::ContextOptions>(
contextOptions | GrContextFactory::kEnableNVPR_ContextOptions);
}
- if (kSRGB_SkColorProfileType == gpuConfig->getProfileType() ||
- kRGBA_F16_SkColorType == gpuConfig->getColorType()) {
+ if (SkColorAndProfileAreGammaCorrect(gpuConfig->getColorType(),
+ gpuConfig->getProfileType())) {
contextOptions = static_cast<GrContextFactory::ContextOptions>(
contextOptions | GrContextFactory::kRequireSRGBSupport_ContextOptions);
}
@@ -1169,8 +1169,7 @@ struct Task {
const SkBitmap* bitmap) {
bool gammaCorrect = false;
if (bitmap) {
- gammaCorrect = bitmap->profileType() == kSRGB_SkColorProfileType
- || bitmap-> colorType() == kRGBA_F16_SkColorType;
+ gammaCorrect = SkImageInfoIsGammaCorrect(bitmap->info());
}
JsonWriter::BitmapResult result;
diff --git a/dm/DMGpuSupport.h b/dm/DMGpuSupport.h
index 2352f83ae4..42c5eb30ae 100644
--- a/dm/DMGpuSupport.h
+++ b/dm/DMGpuSupport.h
@@ -36,6 +36,9 @@ static inline sk_sp<SkSurface> NewGpuSurface(
int samples,
bool useDIText) {
uint32_t flags = useDIText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 0;
+ if (SkImageInfoIsGammaCorrect(info)) {
+ flags |= SkSurfaceProps::kAllowSRGBInputs_Flag;
+ }
SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
return SkSurface::MakeRenderTarget(grFactory->get(type, options), SkBudgeted::kNo,
info, samples, &props);
diff --git a/gm/constcolorprocessor.cpp b/gm/constcolorprocessor.cpp
index 8c91a722ec..37295c78cc 100644
--- a/gm/constcolorprocessor.cpp
+++ b/gm/constcolorprocessor.cpp
@@ -104,7 +104,8 @@ protected:
} else {
skPaint.setColor(kPaintColors[paintType]);
}
- SkAssertResult(SkPaintToGrPaint(context, skPaint, viewMatrix, &grPaint));
+ // SRGBTODO: No sRGB inputs allowed here?
+ SkAssertResult(SkPaintToGrPaint(context, skPaint, viewMatrix, false, &grPaint));
GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
GrColor color = kColors[procColor];
diff --git a/gm/dftext.cpp b/gm/dftext.cpp
index 0d5b1ff4e9..c66064a8d4 100644
--- a/gm/dftext.cpp
+++ b/gm/dftext.cpp
@@ -48,8 +48,12 @@ protected:
// set up offscreen rendering with distance field text
#if SK_SUPPORT_GPU
GrContext* ctx = inputCanvas->getGrContext();
- SkImageInfo info = SkImageInfo::MakeN32Premul(onISize());
- SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
+ SkImageInfo info = SkImageInfo::MakeN32Premul(onISize(),
+ inputCanvas->imageInfo().profileType());
+ SkSurfaceProps canvasProps(SkSurfaceProps::kLegacyFontHost_InitType);
+ uint32_t allowSRGBInputs = inputCanvas->getProps(&canvasProps)
+ ? canvasProps.flags() & SkSurfaceProps::kAllowSRGBInputs_Flag : 0;
+ SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag | allowSRGBInputs,
SkSurfaceProps::kLegacyFontHost_InitType);
auto surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info, 0, &props));
SkCanvas* canvas = surface ? surface->getCanvas() : inputCanvas;
diff --git a/gm/surface.cpp b/gm/surface.cpp
index 901e324397..e104cb5ecf 100644
--- a/gm/surface.cpp
+++ b/gm/surface.cpp
@@ -22,7 +22,7 @@ static sk_sp<SkShader> make_shader() {
}
static sk_sp<SkSurface> make_surface(GrContext* ctx, const SkImageInfo& info, SkPixelGeometry geo,
- int disallowAA, int disallowDither) {
+ int disallowAA, int disallowDither, bool allowSRGBInputs) {
uint32_t flags = 0;
if (disallowAA) {
flags |= SkSurfaceProps::kDisallowAntiAlias_Flag;
@@ -30,6 +30,9 @@ static sk_sp<SkSurface> make_surface(GrContext* ctx, const SkImageInfo& info, Sk
if (disallowDither) {
flags |= SkSurfaceProps::kDisallowDither_Flag;
}
+ if (allowSRGBInputs) {
+ flags |= SkSurfaceProps::kAllowSRGBInputs_Flag;
+ }
SkSurfaceProps props(flags, geo);
if (ctx) {
@@ -74,7 +77,10 @@ protected:
GrContext* ctx = canvas->getGrContext();
// must be opaque to have a hope of testing LCD text
- const SkImageInfo info = SkImageInfo::MakeN32(W, H, kOpaque_SkAlphaType);
+ const SkImageInfo info = SkImageInfo::MakeN32(W, H, kOpaque_SkAlphaType,
+ canvas->imageInfo().profileType());
+ SkSurfaceProps canvasProps(SkSurfaceProps::kLegacyFontHost_InitType);
+ bool allowSRGBInputs = canvas->getProps(&canvasProps) && canvasProps.allowSRGBInputs();
const struct {
SkPixelGeometry fGeo;
@@ -92,7 +98,8 @@ protected:
for (int disallowDither = 0; disallowDither <= 1; ++disallowDither) {
SkScalar y = 0;
for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
- auto surface(make_surface(ctx, info, rec[i].fGeo, disallowAA, disallowDither));
+ auto surface(make_surface(ctx, info, rec[i].fGeo, disallowAA, disallowDither,
+ allowSRGBInputs));
test_draw(surface->getCanvas(), rec[i].fLabel);
surface->draw(canvas, x, y, nullptr);
y += H;
diff --git a/gm/textblobgeometrychange.cpp b/gm/textblobgeometrychange.cpp
index 0632908dfb..b1c5b17988 100644
--- a/gm/textblobgeometrychange.cpp
+++ b/gm/textblobgeometrychange.cpp
@@ -42,8 +42,11 @@ protected:
SkAutoTUnref<const SkTextBlob> blob(builder.build());
- SkImageInfo info = SkImageInfo::MakeN32Premul(200, 200);
- SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+ SkImageInfo info = SkImageInfo::MakeN32Premul(200, 200, canvas->imageInfo().profileType());
+ SkSurfaceProps canvasProps(SkSurfaceProps::kLegacyFontHost_InitType);
+ uint32_t allowSRGBInputs = canvas->getProps(&canvasProps)
+ ? canvasProps.flags() & SkSurfaceProps::kAllowSRGBInputs_Flag : 0;
+ SkSurfaceProps props(allowSRGBInputs, kUnknown_SkPixelGeometry);
auto surface(canvas->makeSurface(info, &props));
if (surface) {
SkCanvas* c = surface->getCanvas();
diff --git a/gm/textblobmixedsizes.cpp b/gm/textblobmixedsizes.cpp
index 82a0dbbd2a..6041e521fd 100644
--- a/gm/textblobmixedsizes.cpp
+++ b/gm/textblobmixedsizes.cpp
@@ -103,8 +103,12 @@ protected:
#if SK_SUPPORT_GPU
// Create a new Canvas to enable DFT
GrContext* ctx = inputCanvas->getGrContext();
- SkImageInfo info = SkImageInfo::MakeN32Premul(onISize());
- SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
+ SkImageInfo info = SkImageInfo::MakeN32Premul(onISize(),
+ inputCanvas->imageInfo().profileType());
+ SkSurfaceProps canvasProps(SkSurfaceProps::kLegacyFontHost_InitType);
+ uint32_t allowSRGBInputs = inputCanvas->getProps(&canvasProps)
+ ? canvasProps.flags() & SkSurfaceProps::kAllowSRGBInputs_Flag : 0;
+ SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag | allowSRGBInputs,
SkSurfaceProps::kLegacyFontHost_InitType);
surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info, 0, &props);
canvas = surface.get() ? surface->getCanvas() : inputCanvas;
diff --git a/gm/textblobrandomfont.cpp b/gm/textblobrandomfont.cpp
index ce726f2e86..285ba5b923 100644
--- a/gm/textblobrandomfont.cpp
+++ b/gm/textblobrandomfont.cpp
@@ -100,8 +100,12 @@ protected:
canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorWHITE));
- SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
- SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+ SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight,
+ canvas->imageInfo().profileType());
+ SkSurfaceProps canvasProps(SkSurfaceProps::kLegacyFontHost_InitType);
+ uint32_t allowSRGBInputs = canvas->getProps(&canvasProps)
+ ? canvasProps.flags() & SkSurfaceProps::kAllowSRGBInputs_Flag : 0;
+ SkSurfaceProps props(allowSRGBInputs, kUnknown_SkPixelGeometry);
auto surface(canvas->makeSurface(info, &props));
if (surface) {
SkPaint paint;
diff --git a/gm/xfermodes3.cpp b/gm/xfermodes3.cpp
index 84bc1e2218..e5c8dd5eb7 100644
--- a/gm/xfermodes3.cpp
+++ b/gm/xfermodes3.cpp
@@ -128,7 +128,9 @@ private:
SkImageInfo baseInfo = baseCanvas->imageInfo();
SkImageInfo info = SkImageInfo::Make(w, h, baseInfo.colorType(), baseInfo.alphaType(),
baseInfo.profileType());
- return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0, nullptr);
+ SkSurfaceProps canvasProps(SkSurfaceProps::kLegacyFontHost_InitType);
+ baseCanvas->getProps(&canvasProps);
+ return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0, &canvasProps);
#else
return nullptr;
#endif
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 91952c3050..8e675b42fc 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -122,6 +122,13 @@ public:
*/
SkImageInfo imageInfo() const;
+ /**
+ * If the canvas is backed by pixels (cpu or gpu), this writes a copy of the SurfaceProps
+ * for the canvas to the location supplied by the caller, and returns true. Otherwise,
+ * return false and leave the supplied props unchanged.
+ */
+ bool getProps(SkSurfaceProps*) const;
+
///////////////////////////////////////////////////////////////////////////
/**
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index 55b08a762c..c15aeccf82 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -41,6 +41,13 @@ public:
virtual SkImageInfo imageInfo() const;
/**
+ * Return SurfaceProps for this device.
+ */
+ const SkSurfaceProps& surfaceProps() const {
+ return fSurfaceProps;
+ }
+
+ /**
* Return the bounds of the device in the coordinate space of the root
* canvas. The root device will have its top-left at 0,0, but other devices
* such as those associated with saveLayer may have a non-zero origin.
@@ -317,10 +324,6 @@ protected:
virtual bool onAccessPixels(SkPixmap*) { return false; }
- const SkSurfaceProps& surfaceProps() const {
- return fSurfaceProps;
- }
-
/**
* PRIVATE / EXPERIMENTAL -- do not call
* This entry point gives the backend an opportunity to take over the rendering
diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h
index b2dda3f021..c55edd36c2 100644
--- a/include/core/SkImageInfo.h
+++ b/include/core/SkImageInfo.h
@@ -318,4 +318,14 @@ private:
{}
};
+///////////////////////////////////////////////////////////////////////////////
+
+static inline bool SkColorAndProfileAreGammaCorrect(SkColorType ct, SkColorProfileType pt) {
+ return kSRGB_SkColorProfileType == pt || kRGBA_F16_SkColorType == ct;
+}
+
+static inline bool SkImageInfoIsGammaCorrect(const SkImageInfo& info) {
+ return SkColorAndProfileAreGammaCorrect(info.colorType(), info.profileType());
+}
+
#endif
diff --git a/include/core/SkSurfaceProps.h b/include/core/SkSurfaceProps.h
index 735561f1dc..bd4fa8e7fc 100644
--- a/include/core/SkSurfaceProps.h
+++ b/include/core/SkSurfaceProps.h
@@ -54,6 +54,17 @@ public:
kDisallowAntiAlias_Flag = 1 << 0,
kDisallowDither_Flag = 1 << 1,
kUseDeviceIndependentFonts_Flag = 1 << 2,
+
+ /**
+ * This flag causes sRGB inputs to the color pipeline (images and other sRGB-tagged
+ * colors) to be gamma-corrected (converted to linear) before use. Without this flag,
+ * texture scaling and filtering is not gamma correct, preserving the behavior of Skia
+ * up through 2015.
+ *
+ * It is recommended to enable this flag when rendering to an sRGB or floating point
+ * surface.
+ */
+ kAllowSRGBInputs_Flag = 1 << 3,
};
/** Deprecated alias used by Chromium. Will be removed. */
static const Flags kUseDistanceFieldFonts_Flag = kUseDeviceIndependentFonts_Flag;
@@ -75,6 +86,7 @@ public:
bool isUseDeviceIndependentFonts() const {
return SkToBool(fFlags & kUseDeviceIndependentFonts_Flag);
}
+ bool allowSRGBInputs() const { return SkToBool(fFlags & kAllowSRGBInputs_Flag); }
private:
SkSurfaceProps();
diff --git a/include/gpu/GrDrawContext.h b/include/gpu/GrDrawContext.h
index 1643cc9678..06954dc1bb 100644
--- a/include/gpu/GrDrawContext.h
+++ b/include/gpu/GrDrawContext.h
@@ -276,6 +276,7 @@ public:
int width() const { return fRenderTarget->width(); }
int height() const { return fRenderTarget->height(); }
int numColorSamples() const { return fRenderTarget->numColorSamples(); }
+ bool allowSRGBInputs() const { return fSurfaceProps.allowSRGBInputs(); }
GrRenderTarget* accessRenderTarget() { return fRenderTarget; }
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index 3f06f092ab..87e0368655 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -63,6 +63,13 @@ public:
void setDisableOutputConversionToSRGB(bool srgb) { fDisableOutputConversionToSRGB = srgb; }
bool getDisableOutputConversionToSRGB() const { return fDisableOutputConversionToSRGB; }
+ /**
+ * Should sRGB inputs be allowed to perform sRGB to linear conversion. With this flag
+ * set to false, sRGB textures will be treated as linear (including filtering).
+ */
+ void setAllowSRGBInputs(bool allowSRGBInputs) { fAllowSRGBInputs = allowSRGBInputs; }
+ bool getAllowSRGBInputs() const { return fAllowSRGBInputs; }
+
const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
fXPFactory.reset(SkSafeRef(xpFactory));
return xpFactory;
@@ -120,6 +127,7 @@ public:
GrPaint& operator=(const GrPaint& paint) {
fAntiAlias = paint.fAntiAlias;
fDisableOutputConversionToSRGB = paint.fDisableOutputConversionToSRGB;
+ fAllowSRGBInputs = paint.fAllowSRGBInputs;
fColor = paint.fColor;
this->resetFragmentProcessors();
@@ -163,6 +171,7 @@ private:
bool fAntiAlias;
bool fDisableOutputConversionToSRGB;
+ bool fAllowSRGBInputs;
GrColor fColor;
};
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index 9be500d3b2..47c13ec02d 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -399,16 +399,6 @@ static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) {
}
}
-static inline bool GrAllowSRGBForDestinationPixelConfig(GrPixelConfig config) {
- switch (config) {
- case kRGBA_8888_GrPixelConfig:
- case kBGRA_8888_GrPixelConfig:
- return false;
- default:
- return true;
- }
-}
-
/**
* Optional bitfield flags that can be set on GrSurfaceDesc (below).
*/
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 2f6477c41d..de69c368cd 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1334,6 +1334,18 @@ SkImageInfo SkCanvas::imageInfo() const {
}
}
+bool SkCanvas::getProps(SkSurfaceProps* props) const {
+ SkBaseDevice* dev = this->getDevice();
+ if (dev) {
+ if (props) {
+ *props = fProps;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
#ifdef SK_SUPPORT_LEGACY_PEEKPIXELS_PARMS
const void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) {
SkPixmap pmap;
@@ -1406,7 +1418,8 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y,
SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache());
SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
- sk_sp<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(&proxy, srcBM));
+ sk_sp<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(&proxy, srcBM,
+ &dstDev->surfaceProps()));
if (!srcImg) {
continue; // something disastrous happened
}
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 3a4090e2d3..1b22856528 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -418,7 +418,8 @@ void SkBaseDevice::drawSpriteWithFilter(const SkDraw& draw, const SkBitmap& bitm
SkAutoTUnref<SkImageFilter::Cache> cache(this->getImageFilterCache());
SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
- sk_sp<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(&proxy, bitmap));
+ sk_sp<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(&proxy, bitmap,
+ &this->surfaceProps()));
if (!srcImg) {
return; // something disastrous happened
}
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 0e0df3625f..743dc2ad1a 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -295,7 +295,8 @@ bool SkImageFilter::filterInputDeprecated(int index, Proxy* proxy, const SkBitma
return true;
}
- sk_sp<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src));
+ // SRGBTODO: Don't handle sRGB here, in anticipation of this code path being deleted.
+ sk_sp<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src, nullptr));
if (!specialSrc) {
return false;
}
@@ -377,7 +378,7 @@ sk_sp<SkSpecialImage> SkImageFilter::onFilterImage(SkSpecialImage* src, const Co
return nullptr;
}
- return SkSpecialImage::internal_fromBM(src->internal_getProxy(), resultBM);
+ return SkSpecialImage::internal_fromBM(src->internal_getProxy(), resultBM, &src->props());
}
bool SkImageFilter::canFilterImageGPU() const {
@@ -418,6 +419,7 @@ bool SkImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src,
SkMatrix matrix(ctx.ctm());
matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
GrPaint paint;
+ // SRGBTODO: Don't handle sRGB here, in anticipation of this code path being deleted.
if (this->asFragmentProcessor(&fp, srcTexture, matrix, bounds)) {
SkASSERT(fp);
paint.addColorFragmentProcessor(fp)->unref();
@@ -620,7 +622,8 @@ bool SkImageFilter::filterInputGPUDeprecated(int index, SkImageFilter::Proxy* pr
return true;
}
- sk_sp<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src));
+ // SRGBTODO: Don't handle sRGB here, in anticipation of this code path being deleted.
+ sk_sp<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src, nullptr));
if (!specialSrc) {
return false;
}
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index 681c224ad8..abac9471cd 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -15,12 +15,14 @@
#include "SkCanvas.h"
#include "SkImage_Base.h"
#include "SkSpecialSurface.h"
+#include "SkSurfacePriv.h"
///////////////////////////////////////////////////////////////////////////////
class SkSpecialImage_Base : public SkSpecialImage {
public:
- SkSpecialImage_Base(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint32_t uniqueID)
- : INHERITED(proxy, subset, uniqueID) {
+ SkSpecialImage_Base(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint32_t uniqueID,
+ const SkSurfaceProps* props)
+ : INHERITED(proxy, subset, uniqueID, props) {
}
virtual ~SkSpecialImage_Base() { }
@@ -52,6 +54,16 @@ static inline const SkSpecialImage_Base* as_SIB(const SkSpecialImage* image) {
return static_cast<const SkSpecialImage_Base*>(image);
}
+SkSpecialImage::SkSpecialImage(SkImageFilter::Proxy* proxy,
+ const SkIRect& subset,
+ uint32_t uniqueID,
+ const SkSurfaceProps* props)
+ : fProps(SkSurfacePropsCopyOrDefault(props))
+ , fSubset(subset)
+ , fUniqueID(kNeedNewImageUniqueID_SpecialImage == uniqueID ? SkNextID::ImageID() : uniqueID)
+ , fProxy(proxy) {
+}
+
sk_sp<SkSpecialImage> SkSpecialImage::makeTextureImage(SkImageFilter::Proxy* proxy,
GrContext* context) {
#if SK_SUPPORT_GPU
@@ -68,7 +80,7 @@ sk_sp<SkSpecialImage> SkSpecialImage::makeTextureImage(SkImageFilter::Proxy* pro
}
if (bmp.empty()) {
- return SkSpecialImage::MakeFromRaster(proxy, SkIRect::MakeEmpty(), bmp);
+ return SkSpecialImage::MakeFromRaster(proxy, SkIRect::MakeEmpty(), bmp, &this->props());
}
SkAutoTUnref<GrTexture> resultTex(
@@ -82,7 +94,7 @@ sk_sp<SkSpecialImage> SkSpecialImage::makeTextureImage(SkImageFilter::Proxy* pro
return SkSpecialImage::MakeFromGpu(proxy,
SkIRect::MakeWH(resultTex->width(), resultTex->height()),
this->uniqueID(),
- resultTex, at);
+ resultTex, &this->props(), at);
#else
return nullptr;
#endif
@@ -126,16 +138,18 @@ sk_sp<SkImage> SkSpecialImage::makeTightSubset(const SkIRect& subset) const {
#endif
sk_sp<SkSpecialImage> SkSpecialImage::internal_fromBM(SkImageFilter::Proxy* proxy,
- const SkBitmap& src) {
+ const SkBitmap& src,
+ const SkSurfaceProps* props) {
// Need to test offset case! (see skbug.com/4967)
if (src.getTexture()) {
return SkSpecialImage::MakeFromGpu(proxy,
src.bounds(),
src.getGenerationID(),
- src.getTexture());
+ src.getTexture(),
+ props);
}
- return SkSpecialImage::MakeFromRaster(proxy, src.bounds(), src);
+ return SkSpecialImage::MakeFromRaster(proxy, src.bounds(), src, props);
}
bool SkSpecialImage::internal_getBM(SkBitmap* result) {
@@ -160,8 +174,9 @@ class SkSpecialImage_Image : public SkSpecialImage_Base {
public:
SkSpecialImage_Image(SkImageFilter::Proxy* proxy,
const SkIRect& subset,
- sk_sp<SkImage> image)
- : INHERITED(proxy, subset, image->uniqueID())
+ sk_sp<SkImage> image,
+ const SkSurfaceProps* props)
+ : INHERITED(proxy, subset, image->uniqueID(), props)
, fImage(image) {
}
@@ -240,7 +255,8 @@ public:
return SkSpecialImage::MakeFromImage(this->internal_getProxy(),
SkIRect::MakeWH(subset.width(), subset.height()),
- subsetImg);
+ subsetImg,
+ &this->props());
}
sk_sp<SkImage> onMakeTightSubset(const SkIRect& subset) const override {
@@ -279,10 +295,11 @@ static bool rect_fits(const SkIRect& rect, int width, int height) {
sk_sp<SkSpecialImage> SkSpecialImage::MakeFromImage(SkImageFilter::Proxy* proxy,
const SkIRect& subset,
- sk_sp<SkImage> image) {
+ sk_sp<SkImage> image,
+ const SkSurfaceProps* props) {
SkASSERT(rect_fits(subset, image->width(), image->height()));
- return sk_make_sp<SkSpecialImage_Image>(proxy, subset, image);
+ return sk_make_sp<SkSpecialImage_Image>(proxy, subset, image, props);
}
///////////////////////////////////////////////////////////////////////////////
@@ -292,8 +309,9 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromImage(SkImageFilter::Proxy* proxy,
class SkSpecialImage_Raster : public SkSpecialImage_Base {
public:
- SkSpecialImage_Raster(SkImageFilter::Proxy* proxy, const SkIRect& subset, const SkBitmap& bm)
- : INHERITED(proxy, subset, bm.getGenerationID())
+ SkSpecialImage_Raster(SkImageFilter::Proxy* proxy, const SkIRect& subset, const SkBitmap& bm,
+ const SkSurfaceProps* props)
+ : INHERITED(proxy, subset, bm.getGenerationID(), props)
, fBitmap(bm) {
if (bm.pixelRef() && bm.pixelRef()->isPreLocked()) {
// we only preemptively lock if there is no chance of triggering something expensive
@@ -306,8 +324,9 @@ public:
const SkIRect& subset,
const SkPixmap& pixmap,
RasterReleaseProc releaseProc,
- ReleaseContext context)
- : INHERITED(proxy, subset, kNeedNewImageUniqueID_SpecialImage) {
+ ReleaseContext context,
+ const SkSurfaceProps* props)
+ : INHERITED(proxy, subset, kNeedNewImageUniqueID_SpecialImage, props) {
fBitmap.installPixels(pixmap.info(), pixmap.writable_addr(),
pixmap.rowBytes(), pixmap.ctable(),
releaseProc, context);
@@ -364,7 +383,8 @@ public:
return SkSpecialImage::MakeFromRaster(this->internal_getProxy(),
SkIRect::MakeWH(subset.width(), subset.height()),
- subsetBM);
+ subsetBM,
+ &this->props());
}
sk_sp<SkImage> onMakeTightSubset(const SkIRect& subset) const override {
@@ -389,23 +409,25 @@ private:
sk_sp<SkSpecialImage> SkSpecialImage::MakeFromRaster(SkImageFilter::Proxy* proxy,
const SkIRect& subset,
- const SkBitmap& bm) {
+ const SkBitmap& bm,
+ const SkSurfaceProps* props) {
SkASSERT(nullptr == bm.getTexture());
SkASSERT(rect_fits(subset, bm.width(), bm.height()));
- return sk_make_sp<SkSpecialImage_Raster>(proxy, subset, bm);
+ return sk_make_sp<SkSpecialImage_Raster>(proxy, subset, bm, props);
}
sk_sp<SkSpecialImage> SkSpecialImage::MakeFromPixmap(SkImageFilter::Proxy* proxy,
const SkIRect& subset,
const SkPixmap& src,
RasterReleaseProc releaseProc,
- ReleaseContext context) {
+ ReleaseContext context,
+ const SkSurfaceProps* props) {
if (!src.addr()) {
return nullptr;
}
- return sk_make_sp<SkSpecialImage_Raster>(proxy, subset, src, releaseProc, context);
+ return sk_make_sp<SkSpecialImage_Raster>(proxy, subset, src, releaseProc, context, props);
}
@@ -417,8 +439,9 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromPixmap(SkImageFilter::Proxy* proxy
class SkSpecialImage_Gpu : public SkSpecialImage_Base {
public:
SkSpecialImage_Gpu(SkImageFilter::Proxy* proxy, const SkIRect& subset,
- uint32_t uniqueID, GrTexture* tex, SkAlphaType at)
- : INHERITED(proxy, subset, uniqueID)
+ uint32_t uniqueID, GrTexture* tex, SkAlphaType at,
+ const SkSurfaceProps* props)
+ : INHERITED(proxy, subset, uniqueID, props)
, fTexture(SkRef(tex))
, fAlphaType(at) {
}
@@ -496,6 +519,7 @@ public:
subset,
this->uniqueID(),
fTexture,
+ &this->props(),
fAlphaType);
}
@@ -539,9 +563,10 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromGpu(SkImageFilter::Proxy* proxy,
const SkIRect& subset,
uint32_t uniqueID,
GrTexture* tex,
+ const SkSurfaceProps* props,
SkAlphaType at) {
SkASSERT(rect_fits(subset, tex->width(), tex->height()));
- return sk_make_sp<SkSpecialImage_Gpu>(proxy, subset, uniqueID, tex, at);
+ return sk_make_sp<SkSpecialImage_Gpu>(proxy, subset, uniqueID, tex, at, props);
}
#else
@@ -550,6 +575,7 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromGpu(SkImageFilter::Proxy* proxy,
const SkIRect& subset,
uint32_t uniqueID,
GrTexture* tex,
+ const SkSurfaceProps* props,
SkAlphaType at) {
return nullptr;
}
diff --git a/src/core/SkSpecialImage.h b/src/core/SkSpecialImage.h
index 4de28ebd16..57785fa445 100644
--- a/src/core/SkSpecialImage.h
+++ b/src/core/SkSpecialImage.h
@@ -10,6 +10,7 @@
#include "SkNextID.h"
#include "SkRefCnt.h"
+#include "SkSurfaceProps.h"
// remove this when internal_getProxy goes away (see skbug.com/4965)
#include "SkImageFilter.h"
@@ -47,6 +48,8 @@ public:
typedef void* ReleaseContext;
typedef void(*RasterReleaseProc)(void* pixels, ReleaseContext);
+ const SkSurfaceProps& props() const { return fProps; }
+
int width() const { return fSubset.width(); }
int height() const { return fSubset.height(); }
const SkIRect& subset() const { return fSubset; }
@@ -69,20 +72,24 @@ public:
static sk_sp<SkSpecialImage> MakeFromImage(SkImageFilter::Proxy*,
const SkIRect& subset,
- sk_sp<SkImage>);
+ sk_sp<SkImage>,
+ const SkSurfaceProps* = nullptr);
static sk_sp<SkSpecialImage> MakeFromRaster(SkImageFilter::Proxy*,
const SkIRect& subset,
- const SkBitmap&);
+ const SkBitmap&,
+ const SkSurfaceProps* = nullptr);
static sk_sp<SkSpecialImage> MakeFromGpu(SkImageFilter::Proxy*,
const SkIRect& subset,
uint32_t uniqueID,
GrTexture*,
+ const SkSurfaceProps* = nullptr,
SkAlphaType at = kPremul_SkAlphaType);
static sk_sp<SkSpecialImage> MakeFromPixmap(SkImageFilter::Proxy*,
const SkIRect& subset,
const SkPixmap&,
RasterReleaseProc,
- ReleaseContext);
+ ReleaseContext,
+ const SkSurfaceProps* = nullptr);
/**
* Create a new special surface with a backend that is compatible with this special image.
@@ -110,7 +117,8 @@ public:
// These three internal methods will go away (see skbug.com/4965)
bool internal_getBM(SkBitmap* result);
- static sk_sp<SkSpecialImage> internal_fromBM(SkImageFilter::Proxy*, const SkBitmap&);
+ static sk_sp<SkSpecialImage> internal_fromBM(SkImageFilter::Proxy*, const SkBitmap&,
+ const SkSurfaceProps*);
SkImageFilter::Proxy* internal_getProxy() const;
// TODO: hide this when GrLayerHoister uses SkSpecialImages more fully (see skbug.com/5063)
@@ -135,12 +143,8 @@ public:
bool peekPixels(SkPixmap*) const;
protected:
- SkSpecialImage(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint32_t uniqueID)
- : fSubset(subset)
- , fUniqueID(kNeedNewImageUniqueID_SpecialImage == uniqueID ? SkNextID::ImageID()
- : uniqueID)
- , fProxy(proxy) {
- }
+ SkSpecialImage(SkImageFilter::Proxy*, const SkIRect& subset, uint32_t uniqueID,
+ const SkSurfaceProps*);
// The following 2 are for testing and shouldn't be used.
friend class TestingSpecialImageAccess;
@@ -154,8 +158,9 @@ protected:
SkImageFilter::Proxy* proxy() const { return fProxy; }
private:
- const SkIRect fSubset;
- const uint32_t fUniqueID;
+ const SkSurfaceProps fProps;
+ const SkIRect fSubset;
+ const uint32_t fUniqueID;
// TODO: remove this ASAP (see skbug.com/4965)
SkImageFilter::Proxy* fProxy;
diff --git a/src/core/SkSpecialSurface.cpp b/src/core/SkSpecialSurface.cpp
index 2ac71ffb52..7dced71eb2 100644
--- a/src/core/SkSpecialSurface.cpp
+++ b/src/core/SkSpecialSurface.cpp
@@ -82,7 +82,8 @@ public:
~SkSpecialSurface_Raster() override { }
sk_sp<SkSpecialImage> onMakeImageSnapshot() override {
- return SkSpecialImage::MakeFromRaster(this->proxy(), this->subset(), fBitmap);
+ return SkSpecialImage::MakeFromRaster(this->proxy(), this->subset(), fBitmap,
+ &this->props());
}
private:
@@ -139,7 +140,8 @@ public:
sk_sp<SkSpecialImage> onMakeImageSnapshot() override {
return SkSpecialImage::MakeFromGpu(this->proxy(), this->subset(),
- kNeedNewImageUniqueID_SpecialImage, fTexture);
+ kNeedNewImageUniqueID_SpecialImage, fTexture,
+ &this->props());
}
private:
diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp
index b7745e27bf..10c8a0b17b 100644
--- a/src/effects/SkBlurImageFilter.cpp
+++ b/src/effects/SkBlurImageFilter.cpp
@@ -113,6 +113,7 @@ sk_sp<SkSpecialImage> SkBlurImageFilter::onFilterImage(SkSpecialImage* source,
SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(inputTexture->getContext(),
inputTexture,
false,
+ source->props().allowSRGBInputs(),
SkRect::Make(dstBounds),
&inputBoundsF,
sigma.x(),
@@ -124,7 +125,7 @@ sk_sp<SkSpecialImage> SkBlurImageFilter::onFilterImage(SkSpecialImage* source,
return SkSpecialImage::MakeFromGpu(source->internal_getProxy(),
SkIRect::MakeWH(dstBounds.width(), dstBounds.height()),
kNeedNewImageUniqueID_SpecialImage,
- tex);
+ tex, &source->props());
}
#endif
@@ -216,7 +217,7 @@ sk_sp<SkSpecialImage> SkBlurImageFilter::onFilterImage(SkSpecialImage* source,
return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
SkIRect::MakeWH(dstBounds.width(),
dstBounds.height()),
- dst);
+ dst, &source->props());
}
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index bb6a8a5ae6..609e168f01 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -1243,7 +1243,8 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src,
// gaussianBlur. Otherwise, we need to save it for later compositing.
bool isNormalBlur = (kNormal_SkBlurStyle == fBlurStyle);
*result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOverwriteSrc,
- clipRect, nullptr, xformedSigma, xformedSigma);
+ false, clipRect, nullptr,
+ xformedSigma, xformedSigma);
if (nullptr == *result) {
return false;
}
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index 447a20bcb2..6debea16e4 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -431,6 +431,7 @@ bool SkDisplacementMapEffect::filterImageGPUDeprecated(Proxy* proxy, const SkBit
ctx.ctm().mapVectors(&scale, 1);
GrPaint paint;
+ // SRGBTODO: AllowSRGBInputs?
SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displacement);
offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displacementOffset.fX),
SkIntToScalar(colorOffset.fY - displacementOffset.fY));
diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp
index c43f27303e..90619f9dc8 100644
--- a/src/effects/SkGpuBlurUtils.cpp
+++ b/src/effects/SkGpuBlurUtils.cpp
@@ -56,6 +56,7 @@ static void convolve_gaussian_1d(GrDrawContext* drawContext,
bool useBounds,
float bounds[2]) {
GrPaint paint;
+ paint.setAllowSRGBInputs(drawContext->allowSRGBInputs());
SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian(
texture, direction, radius, sigma, useBounds, bounds));
paint.addColorFragmentProcessor(conv);
@@ -78,6 +79,7 @@ static void convolve_gaussian_2d(GrDrawContext* drawContext,
SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
GrPaint paint;
+ paint.setAllowSRGBInputs(drawContext->allowSRGBInputs());
SkIRect bounds;
if (srcBounds) {
srcBounds->roundOut(&bounds);
@@ -164,6 +166,7 @@ static void convolve_gaussian(GrDrawContext* drawContext,
GrTexture* GaussianBlur(GrContext* context,
GrTexture* srcTexture,
bool canClobberSrc,
+ bool allowSRGBInputs,
const SkRect& dstBounds,
const SkRect* srcBounds,
float sigmaX,
@@ -229,6 +232,7 @@ GrTexture* GaussianBlur(GrContext* context,
for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
GrPaint paint;
+ paint.setAllowSRGBInputs(allowSRGBInputs);
SkMatrix matrix;
matrix.setIDiv(srcTexture->width(), srcTexture->height());
SkRect dstRect(srcRect);
@@ -268,6 +272,9 @@ GrTexture* GaussianBlur(GrContext* context,
localSrcBounds = srcRect;
}
+ SkSurfaceProps props(allowSRGBInputs ? SkSurfaceProps::kAllowSRGBInputs_Flag : 0,
+ SkSurfaceProps::kLegacyFontHost_InitType);
+
// For really small blurs (certainly no wider than 5x5 on desktop gpus) it is faster to just
// launch a single non separable kernel vs two launches
srcRect = localDstBounds;
@@ -277,7 +284,7 @@ GrTexture* GaussianBlur(GrContext* context,
SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY));
SkAutoTUnref<GrDrawContext> dstDrawContext(
- context->drawContext(dstTexture->asRenderTarget()));
+ context->drawContext(dstTexture->asRenderTarget(), &props));
if (!dstDrawContext) {
return nullptr;
}
@@ -311,7 +318,7 @@ GrTexture* GaussianBlur(GrContext* context,
}
SkAutoTUnref<GrDrawContext> dstDrawContext(
- context->drawContext(dstTexture->asRenderTarget()));
+ context->drawContext(dstTexture->asRenderTarget(), &props));
if (!dstDrawContext) {
return nullptr;
}
@@ -344,7 +351,7 @@ GrTexture* GaussianBlur(GrContext* context,
}
SkAutoTUnref<GrDrawContext> dstDrawContext(
- context->drawContext(dstTexture->asRenderTarget()));
+ context->drawContext(dstTexture->asRenderTarget(), &props));
if (!dstDrawContext) {
return nullptr;
}
@@ -375,6 +382,7 @@ GrTexture* GaussianBlur(GrContext* context,
matrix.setIDiv(srcTexture->width(), srcTexture->height());
GrPaint paint;
+ paint.setAllowSRGBInputs(allowSRGBInputs);
// FIXME: this should be mitchell, not bilinear.
GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
paint.addColorTextureProcessor(srcTexture, matrix, params);
diff --git a/src/effects/SkGpuBlurUtils.h b/src/effects/SkGpuBlurUtils.h
index 013d11b517..e81e5daddb 100644
--- a/src/effects/SkGpuBlurUtils.h
+++ b/src/effects/SkGpuBlurUtils.h
@@ -26,6 +26,7 @@ namespace SkGpuBlurUtils {
* @param srcTexture The source texture to be blurred.
* @param canClobberSrc If true, srcTexture may be overwritten, and
* may be returned as the result.
+ * @param allowSRGBInputs Should sRGB inputs be allowed to perform sRGB to linear conversion.
* @param dstBounds The destination bounds, relative to the source texture.
* @param srcBounds The source bounds, relative to the source texture. If non-null,
* no pixels will be sampled outside of this rectangle.
@@ -37,6 +38,7 @@ namespace SkGpuBlurUtils {
GrTexture* GaussianBlur(GrContext* context,
GrTexture* srcTexture,
bool canClobberSrc,
+ bool allowSRGBInputs,
const SkRect& dstBounds,
const SkRect* srcBounds,
float sigmaX,
diff --git a/src/effects/SkImageSource.cpp b/src/effects/SkImageSource.cpp
index cf8cae2c39..6a4eb8d3aa 100644
--- a/src/effects/SkImageSource.cpp
+++ b/src/effects/SkImageSource.cpp
@@ -68,11 +68,13 @@ sk_sp<SkSpecialImage> SkImageSource::onFilterImage(SkSpecialImage* source, const
offset->fX = offset->fY = 0;
return SkSpecialImage::MakeFromImage(source->internal_getProxy(),
SkIRect::MakeWH(fImage->width(), fImage->height()),
- fImage);
+ fImage,
+ &source->props());
}
const SkIRect dstIRect = dstRect.roundOut();
+ // SRGBTODO: Propagate SkColorType?
const SkImageInfo info = SkImageInfo::MakeN32(dstIRect.width(), dstIRect.height(),
kPremul_SkAlphaType);
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index c27a55476f..e276dc0fde 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -387,6 +387,7 @@ void SkLightingImageFilterInternal::drawRect(GrDrawContext* drawContext,
const SkIRect& bounds) const {
SkRect srcRect = dstRect.makeOffset(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()));
GrPaint paint;
+ // SRGBTODO: AllowSRGBInputs?
GrFragmentProcessor* fp = this->getFragmentProcessor(src, matrix, srcBounds, boundaryMode);
paint.addColorFragmentProcessor(fp)->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index ea714e59f6..616c0d2e8b 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -370,6 +370,7 @@ static void apply_morphology_rect(GrDrawContext* drawContext,
float bounds[2],
Gr1DKernelEffect::Direction direction) {
GrPaint paint;
+ // SRGBTODO: AllowSRGBInputs?
paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture,
direction,
radius,
@@ -389,6 +390,7 @@ static void apply_morphology_rect_no_bounds(GrDrawContext* drawContext,
GrMorphologyEffect::MorphologyType morphType,
Gr1DKernelEffect::Direction direction) {
GrPaint paint;
+ // SRGBTODO: AllowSRGBInputs?
paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture,
direction,
radius,
@@ -511,7 +513,7 @@ static sk_sp<SkSpecialImage> apply_morphology(SkSpecialImage* input,
return SkSpecialImage::MakeFromGpu(input->internal_getProxy(),
SkIRect::MakeWH(rect.width(), rect.height()),
kNeedNewImageUniqueID_SpecialImage,
- srcTexture);
+ srcTexture, &input->props());
}
#endif
@@ -619,5 +621,5 @@ sk_sp<SkSpecialImage> SkMorphologyImageFilter::onFilterImage(SkSpecialImage* sou
return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
SkIRect::MakeWH(bounds.width(), bounds.height()),
- dst);
+ dst, &source->props());
}
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index a29136a0dd..330f839152 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -174,6 +174,7 @@ bool SkXfermodeImageFilter::filterImageGPUDeprecated(Proxy* proxy,
}
GrPaint paint;
+ // SRGBTODO: AllowSRGBInputs?
SkAutoTUnref<const GrFragmentProcessor> bgFP;
if (backgroundTex) {
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index 65b18a5edc..0dd518fdf7 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -335,7 +335,8 @@ void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
}
GrPaint grPaint;
- if (!SkPaintToGrPaint(context, paint, viewMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(context, paint, viewMatrix, drawContext->allowSRGBInputs(),
+ &grPaint)) {
return;
}
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 1d6bb32142..c223a60213 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -366,6 +366,8 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
if (!drawContext) {
return false;
}
+ // SRGBTODO: AllowSRGBInputs? (We could force it on here, so we don't need the
+ // per-texture override in config conversion effect?)
GrPaint paint;
paint.addColorFragmentProcessor(fp);
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
@@ -476,6 +478,8 @@ bool GrContext::readSurfacePixels(GrSurface* src,
GrConfigConversionEffect::kNone_PMConversion, textureMatrix));
}
if (fp) {
+ // SRGBTODO: AllowSRGBInputs? (We could force it on here, so we don't need the
+ // per-texture override in config conversion effect?)
GrPaint paint;
paint.addColorFragmentProcessor(fp);
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp
index 80ea3cdc50..dd8a48547a 100644
--- a/src/gpu/GrLayerHoister.cpp
+++ b/src/gpu/GrLayerHoister.cpp
@@ -306,7 +306,8 @@ void GrLayerHoister::FilterLayer(GrContext* context,
const SkIRect subset = SkIRect::MakeWH(layer->texture()->width(), layer->texture()->height());
sk_sp<SkSpecialImage> img(SkSpecialImage::MakeFromGpu(&proxy, subset,
kNeedNewImageUniqueID_SpecialImage,
- layer->texture()));
+ layer->texture(),
+ &device->surfaceProps()));
SkIPoint offset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> result(layer->filter()->filterImage(img.get(),
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index af93e8fa90..f41469e08e 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -15,6 +15,7 @@
GrPaint::GrPaint()
: fAntiAlias(false)
, fDisableOutputConversionToSRGB(false)
+ , fAllowSRGBInputs(false)
, fColor(GrColor_WHITE) {}
void GrPaint::setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) {
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index d8e2e5d98e..55cbf345a0 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -84,6 +84,9 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
if (builder.getDisableOutputConversionToSRGB()) {
pipeline->fFlags |= kDisableOutputConversionToSRGB_Flag;
}
+ if (builder.getAllowSRGBInputs()) {
+ pipeline->fFlags |= kAllowSRGBInputs_Flag;
+ }
int firstColorProcessorIdx = args.fOpts.fColorPOI.firstEffectiveProcessorIndex();
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index bdcc7d991b..f64b875f13 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -148,6 +148,9 @@ public:
bool getDisableOutputConversionToSRGB() const {
return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
}
+ bool getAllowSRGBInputs() const {
+ return SkToBool(fFlags & kAllowSRGBInputs_Flag);
+ }
GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
return this->getXferProcessor().xferBarrierType(fRenderTarget.get(), caps);
@@ -190,6 +193,7 @@ private:
kHWAA_Flag = 0x1,
kSnapVertices_Flag = 0x2,
kDisableOutputConversionToSRGB_Flag = 0x4,
+ kAllowSRGBInputs_Flag = 0x8,
};
typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp
index d82ee1c0c2..252c26577e 100644
--- a/src/gpu/GrPipelineBuilder.cpp
+++ b/src/gpu/GrPipelineBuilder.cpp
@@ -46,6 +46,8 @@ GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, GrRenderTarget* rt, c
rt->isUnifiedMultisampled() && paint.isAntiAlias());
this->setState(GrPipelineBuilder::kDisableOutputConversionToSRGB_Flag,
paint.getDisableOutputConversionToSRGB());
+ this->setState(GrPipelineBuilder::kAllowSRGBInputs_Flag,
+ paint.getAllowSRGBInputs());
}
//////////////////////////////////////////////////////////////////////////////s
diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h
index 4190070efb..08ac5db8b7 100644
--- a/src/gpu/GrPipelineBuilder.h
+++ b/src/gpu/GrPipelineBuilder.h
@@ -288,7 +288,12 @@ public:
*/
kDisableOutputConversionToSRGB_Flag = 0x04,
- kLast_Flag = kDisableOutputConversionToSRGB_Flag,
+ /**
+ * Allow sRGB -> linear conversion when reading from sRGB inputs.
+ */
+ kAllowSRGBInputs_Flag = 0x08,
+
+ kLast_Flag = kAllowSRGBInputs_Flag,
};
bool isHWAntialias() const { return SkToBool(fFlags & kHWAntialias_Flag); }
@@ -296,6 +301,8 @@ public:
return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); }
bool getDisableOutputConversionToSRGB() const {
return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag); }
+ bool getAllowSRGBInputs() const {
+ return SkToBool(fFlags & kAllowSRGBInputs_Flag); }
/**
* Enable render state settings.
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index d0c526b170..d9727415b2 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -396,7 +396,8 @@ void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPaint", fContext);
GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -446,7 +447,8 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mode) {
GrStrokeInfo strokeInfo(paint, SkPaint::kStroke_Style);
GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
SkPath path;
@@ -466,7 +468,8 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
}
GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -518,7 +521,8 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, const SkPaint
}
GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -536,7 +540,8 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
CHECK_SHOULD_DRAW(draw);
GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -611,7 +616,8 @@ void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
if (stroke.isFillStyle() && !paint.getMaskFilter() && !paint.getPathEffect()) {
GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -655,7 +661,8 @@ void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint
}
GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -1139,7 +1146,8 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
GrPaint grPaint;
if (!SkPaintToGrPaintWithTexture(this->context(), paint, viewMatrix, fp,
- kAlpha_8_SkColorType == bitmap.colorType(), &grPaint)) {
+ kAlpha_8_SkColorType == bitmap.colorType(),
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -1233,7 +1241,8 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
} else {
fp.reset(GrFragmentProcessor::MulOutputByInputAlpha(fp));
}
- if (!SkPaintToGrPaintReplaceShader(this->context(), paint, fp, &grPaint)) {
+ if (!SkPaintToGrPaintReplaceShader(this->context(), paint, fp,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -1393,7 +1402,8 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
fp.reset(GrFragmentProcessor::MulOutputByInputAlpha(fp));
}
- if (!SkPaintToGrPaintReplaceShader(this->context(), paint, fp, &grPaint)) {
+ if (!SkPaintToGrPaintReplaceShader(this->context(), paint, fp,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -1532,7 +1542,8 @@ void SkGpuDevice::drawProducerNine(const SkDraw& draw, GrTextureProducer* produc
&kMode));
GrPaint grPaint;
if (!SkPaintToGrPaintWithTexture(this->context(), paint, *draw.fMatrix, fp,
- producer->isAlphaOnly(), &grPaint)) {
+ producer->isAlphaOnly(),
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -1599,7 +1610,8 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
GrPaint grPaint;
// we ignore the shader if texs is null.
- if (!SkPaintToGrPaintNoShader(this->context(), copy, &grPaint)) {
+ if (!SkPaintToGrPaintNoShader(this->context(), copy,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -1671,12 +1683,14 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
colorMode = SkXfermode::kModulate_Mode;
}
if (!SkPaintToGrPaintWithXfermode(this->context(), paint, *draw.fMatrix, colorMode,
- false, &grPaint)) {
+ false, this->surfaceProps().allowSRGBInputs(),
+ &grPaint)) {
return;
}
} else {
// We have a shader, but no colors to blend it against.
- if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
}
@@ -1684,12 +1698,15 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
if (colors) {
// We have colors, but either have no shader or no texture coords (which implies that
// we should ignore the shader).
- if (!SkPaintToGrPaintWithPrimitiveColor(this->context(), paint, &grPaint)) {
+ if (!SkPaintToGrPaintWithPrimitiveColor(this->context(), paint,
+ this->surfaceProps().allowSRGBInputs(),
+ &grPaint)) {
return;
}
} else {
// No colors and no shaders. Just draw with the paint color.
- if (!SkPaintToGrPaintNoShader(this->context(), paint, &grPaint)) {
+ if (!SkPaintToGrPaintNoShader(this->context(), paint,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
}
@@ -1727,11 +1744,12 @@ void SkGpuDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRS
GrPaint grPaint;
if (colors) {
if (!SkPaintToGrPaintWithXfermode(this->context(), p, *draw.fMatrix, mode, true,
- &grPaint)) {
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
} else {
- if (!SkPaintToGrPaint(this->context(), p, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), p, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
}
@@ -1750,7 +1768,8 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawText", fContext);
GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
@@ -1768,7 +1787,8 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteL
CHECK_SHOULD_DRAW(draw);
GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index 1be2dd59bc..8464895eab 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -206,7 +206,7 @@ void SkGpuDevice::drawTextureProducerImpl(GrTextureProducer* producer,
GrPaint grPaint;
if (!SkPaintToGrPaintWithTexture(fContext, paint, viewMatrix, fp, producer->isAlphaOnly(),
- &grPaint)) {
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 905af81a79..716909133a 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -495,8 +495,10 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
const GrFragmentProcessor** shaderProcessor,
SkXfermode::Mode* primColorMode,
bool primitiveIsSrc,
+ bool allowSRGBInputs,
GrPaint* grPaint) {
grPaint->setAntiAlias(skPaint.isAntiAlias());
+ grPaint->setAllowSRGBInputs(allowSRGBInputs);
// Setup the initial color considering the shader, the SkPaint color, and the presence or not
// of per-vertex colors.
@@ -623,31 +625,34 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
}
bool SkPaintToGrPaint(GrContext* context, const SkPaint& skPaint, const SkMatrix& viewM,
- GrPaint* grPaint) {
- return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, nullptr, false, grPaint);
+ bool allowSRGBInputs, GrPaint* grPaint) {
+ return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, nullptr, false,
+ allowSRGBInputs, grPaint);
}
/** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. */
bool SkPaintToGrPaintReplaceShader(GrContext* context,
const SkPaint& skPaint,
const GrFragmentProcessor* shaderFP,
+ bool allowSRGBInputs,
GrPaint* grPaint) {
if (!shaderFP) {
return false;
}
return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), &shaderFP, nullptr, false,
- grPaint);
+ allowSRGBInputs, grPaint);
}
/** Ignores the SkShader (if any) on skPaint. */
bool SkPaintToGrPaintNoShader(GrContext* context,
const SkPaint& skPaint,
+ bool allowSRGBInputs,
GrPaint* grPaint) {
// Use a ptr to a nullptr to to indicate that the SkShader is ignored and not replaced.
static const GrFragmentProcessor* kNullShaderFP = nullptr;
static const GrFragmentProcessor** kIgnoreShader = &kNullShaderFP;
return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), kIgnoreShader, nullptr, false,
- grPaint);
+ allowSRGBInputs, grPaint);
}
/** Blends the SkPaint's shader (or color if no shader) with a per-primitive color which must
@@ -657,9 +662,10 @@ bool SkPaintToGrPaintWithXfermode(GrContext* context,
const SkMatrix& viewM,
SkXfermode::Mode primColorMode,
bool primitiveIsSrc,
+ bool allowSRGBInputs,
GrPaint* grPaint) {
return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, &primColorMode, primitiveIsSrc,
- grPaint);
+ allowSRGBInputs, grPaint);
}
bool SkPaintToGrPaintWithTexture(GrContext* context,
@@ -667,6 +673,7 @@ bool SkPaintToGrPaintWithTexture(GrContext* context,
const SkMatrix& viewM,
const GrFragmentProcessor* fp,
bool textureIsAlphaOnly,
+ bool allowSRGBInputs,
GrPaint* grPaint) {
SkAutoTUnref<const GrFragmentProcessor> shaderFP;
if (textureIsAlphaOnly) {
@@ -687,7 +694,7 @@ bool SkPaintToGrPaintWithTexture(GrContext* context,
shaderFP.reset(GrFragmentProcessor::MulOutputByInputAlpha(fp));
}
- return SkPaintToGrPaintReplaceShader(context, paint, shaderFP.get(), grPaint);
+ return SkPaintToGrPaintReplaceShader(context, paint, shaderFP.get(), allowSRGBInputs, grPaint);
}
diff --git a/src/gpu/SkGrPriv.h b/src/gpu/SkGrPriv.h
index f43a4e9595..46be3a53cf 100644
--- a/src/gpu/SkGrPriv.h
+++ b/src/gpu/SkGrPriv.h
@@ -48,11 +48,13 @@ void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pix
bool SkPaintToGrPaint(GrContext*,
const SkPaint& skPaint,
const SkMatrix& viewM,
+ bool allowSRGBInputs,
GrPaint* grPaint);
/** Same as above but ignores the SkShader (if any) on skPaint. */
bool SkPaintToGrPaintNoShader(GrContext* context,
const SkPaint& skPaint,
+ bool allowSRGBInputs,
GrPaint* grPaint);
/** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. The processor
@@ -61,6 +63,7 @@ bool SkPaintToGrPaintNoShader(GrContext* context,
bool SkPaintToGrPaintReplaceShader(GrContext*,
const SkPaint& skPaint,
const GrFragmentProcessor* shaderFP,
+ bool allowSRGBInputs,
GrPaint* grPaint);
/** Blends the SkPaint's shader (or color if no shader) with the color which specified via a
@@ -72,6 +75,7 @@ bool SkPaintToGrPaintWithXfermode(GrContext* context,
const SkMatrix& viewM,
SkXfermode::Mode primColorMode,
bool primitiveIsSrc,
+ bool allowSRGBInputs,
GrPaint* grPaint);
/** This is used when there is a primitive color, but the shader should be ignored. Currently,
@@ -79,9 +83,9 @@ bool SkPaintToGrPaintWithXfermode(GrContext* context,
unpremultiplied so that interpolation is done in unpremul space. The paint's alpha will be
applied to the primitive color after interpolation. */
inline bool SkPaintToGrPaintWithPrimitiveColor(GrContext* context, const SkPaint& skPaint,
- GrPaint* grPaint) {
+ bool allowSRGBInputs, GrPaint* grPaint) {
return SkPaintToGrPaintWithXfermode(context, skPaint, SkMatrix::I(), SkXfermode::kDst_Mode,
- false, grPaint);
+ false, allowSRGBInputs, grPaint);
}
/** This is used when there may or may not be a shader, and the caller wants to plugin a texture
@@ -91,6 +95,7 @@ bool SkPaintToGrPaintWithTexture(GrContext* context,
const SkMatrix& viewM,
const GrFragmentProcessor* fp,
bool textureIsAlphaOnly,
+ bool allowSRGBInputs,
GrPaint* grPaint);
//////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index c8c12a388d..0063b3d16c 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -2051,15 +2051,13 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
SkSTArray<8, const GrTextureAccess*> textureAccesses;
program->setData(primProc, pipeline, &textureAccesses);
- GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
- bool allowSRGB = GrAllowSRGBForDestinationPixelConfig(glRT->config());
-
int numTextureAccesses = textureAccesses.count();
for (int i = 0; i < numTextureAccesses; i++) {
- this->bindTexture(i, textureAccesses[i]->getParams(), allowSRGB,
+ this->bindTexture(i, textureAccesses[i]->getParams(), pipeline.getAllowSRGBInputs(),
static_cast<GrGLTexture*>(textureAccesses[i]->getTexture()));
}
+ GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
this->flushStencil(pipeline.getStencil());
this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->origin());
this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !pipeline.getStencil().isDisabled());
diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp
index ec9e40cbae..918d6d29f7 100644
--- a/src/gpu/text/GrAtlasTextContext.cpp
+++ b/src/gpu/text/GrAtlasTextContext.cpp
@@ -112,7 +112,7 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrDrawContext* dc,
// Though for the time being runs in the textblob can override the paint, they only touch font
// info.
GrPaint grPaint;
- if (!SkPaintToGrPaint(context, skPaint, viewMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(context, skPaint, viewMatrix, props.allowSRGBInputs(), &grPaint)) {
return;
}
@@ -382,7 +382,8 @@ DRAW_BATCH_TEST_DEFINE(TextBlobBatch) {
skPaint.setSubpixelText(random->nextBool());
GrPaint grPaint;
- if (!SkPaintToGrPaint(context, skPaint, viewMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(context, skPaint, viewMatrix, gSurfaceProps.allowSRGBInputs(),
+ &grPaint)) {
SkFAIL("couldn't convert paint\n");
}
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index 4c2a615a66..151858b8b9 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -165,7 +165,7 @@ void GrStencilAndCoverTextContext::uncachedDrawTextBlob(GrContext* context,
runPaint.setFlags(GrTextUtils::FilterTextFlags(props, runPaint));
GrPaint grPaint;
- if (!SkPaintToGrPaint(context, runPaint, viewMatrix, &grPaint)) {
+ if (!SkPaintToGrPaint(context, runPaint, viewMatrix, dc->allowSRGBInputs(), &grPaint)) {
return;
}
@@ -220,7 +220,7 @@ void GrStencilAndCoverTextContext::drawTextBlob(GrContext* context, GrDrawContex
}
GrPaint paint;
- if (!SkPaintToGrPaint(context, skPaint, viewMatrix, &paint)) {
+ if (!SkPaintToGrPaint(context, skPaint, viewMatrix, dc->allowSRGBInputs(), &paint)) {
return;
}
diff --git a/src/views/SkWindow.cpp b/src/views/SkWindow.cpp
index 481a1f9eb2..bcc7b0298f 100644
--- a/src/views/SkWindow.cpp
+++ b/src/views/SkWindow.cpp
@@ -70,6 +70,13 @@ void SkWindow::resize(int width, int height) {
void SkWindow::setColorType(SkColorType ct, SkColorProfileType pt) {
const SkImageInfo& info = fBitmap.info();
this->resize(SkImageInfo::Make(info.width(), info.height(), ct, kPremul_SkAlphaType, pt));
+
+ // Set the global flag that enables or disables "legacy" mode, depending on our format.
+ // With sRGB 32-bit or linear FP 16, we turn on gamma-correct handling of inputs:
+ SkSurfaceProps props = this->getSurfaceProps();
+ uint32_t flags = (props.flags() & ~SkSurfaceProps::kAllowSRGBInputs_Flag) |
+ (SkColorAndProfileAreGammaCorrect(ct, pt) ? SkSurfaceProps::kAllowSRGBInputs_Flag : 0);
+ this->setSurfaceProps(SkSurfaceProps(flags, props.pixelGeometry()));
}
bool SkWindow::handleInval(const SkRect* localR) {
@@ -333,9 +340,7 @@ GrRenderTarget* SkWindow::renderTarget(const AttachmentInfo& attachmentInfo,
//
// Also, we may not have real sRGB support (ANGLE, in particular), so check for
// that, and fall back to L32:
- desc.fConfig = grContext->caps()->srgbSupport() &&
- (info().profileType() == kSRGB_SkColorProfileType ||
- info().colorType() == kRGBA_F16_SkColorType)
+ desc.fConfig = grContext->caps()->srgbSupport() && SkImageInfoIsGammaCorrect(info())
? kSkiaGamma8888_GrPixelConfig
: kSkia8888_GrPixelConfig;
desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 818bf6462d..1fec1a694b 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -155,7 +155,8 @@ void SkGpuDevice::drawTexture(GrTexture* tex, const SkRect& dst, const SkPaint&
GrPaint grPaint;
SkMatrix mat;
mat.reset();
- if (!SkPaintToGrPaint(this->context(), paint, mat, &grPaint)) {
+ if (!SkPaintToGrPaint(this->context(), paint, mat,
+ this->surfaceProps().allowSRGBInputs(), &grPaint)) {
return;
}
SkMatrix textureMat;