aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
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 /src/core
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
Diffstat (limited to 'src/core')
-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
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: