diff options
author | brianosman <brianosman@google.com> | 2016-04-06 07:38:23 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-04-06 07:38:23 -0700 |
commit | 898235c4864df66aa7f6d32bc2a8b8551040ce1e (patch) | |
tree | 5fb30f04825c59a970a208cabadd4bad0be283b3 /src/core | |
parent | 1817d282cda17cb8c2db0ac6fdc937743c026016 (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
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkCanvas.cpp | 15 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 3 | ||||
-rw-r--r-- | src/core/SkImageFilter.cpp | 9 | ||||
-rw-r--r-- | src/core/SkSpecialImage.cpp | 74 | ||||
-rw-r--r-- | src/core/SkSpecialImage.h | 29 | ||||
-rw-r--r-- | src/core/SkSpecialSurface.cpp | 6 |
6 files changed, 93 insertions, 43 deletions
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: |