aboutsummaryrefslogtreecommitdiffhomepage
path: root/dm
diff options
context:
space:
mode:
authorGravatar scroggo <scroggo@google.com>2016-02-03 09:42:42 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-03 09:42:42 -0800
commitc5560bef14149f4c945a4536988aeba1a16adedc (patch)
treed62cecc289bb7c0ad9083258669179a64fd87d59 /dm
parent8ca88e41aa76bc4da568936de9299ec3f8762d9c (diff)
Support decoding opaque to *premul
If a client requests unpremul or premul from an opaque SkCodec, support it. The opaque image can be treated as any of them, though it will be less efficient to draw than if the client had used opaque. Change the filling code (i.e. for incomplete images) to base its color on the source alpha type. Prior to adding the support to decode opaque to any, it was fine to use either source or dest (which would have yielded the same result). If the client requests non-opaque, we do not want this to switch the fill value from black to transparent. This also allows simplifying the signatures for getFillValue and onGetFillValue. In CodexTest, expect the same result when decoding opaque to *premul, and compare to the opaque version. BUG=skia:4616 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1641273003 Review URL: https://codereview.chromium.org/1641273003
Diffstat (limited to 'dm')
-rw-r--r--dm/DM.cpp59
-rw-r--r--dm/DMSrcSink.cpp31
-rw-r--r--dm/DMSrcSink.h6
3 files changed, 66 insertions, 30 deletions
diff --git a/dm/DM.cpp b/dm/DM.cpp
index eb40113a9b..e5a6e4d196 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -225,7 +225,7 @@ static void push_src(ImplicitString tag, ImplicitString options, Src* s) {
}
static void push_codec_src(Path path, CodecSrc::Mode mode, CodecSrc::DstColorType dstColorType,
- float scale) {
+ SkAlphaType dstAlphaType, float scale) {
SkString folder;
switch (mode) {
case CodecSrc::kCodec_Mode:
@@ -259,16 +259,30 @@ static void push_codec_src(Path path, CodecSrc::Mode mode, CodecSrc::DstColorTyp
break;
}
+ switch (dstAlphaType) {
+ case kOpaque_SkAlphaType:
+ folder.append("_opaque");
+ break;
+ case kPremul_SkAlphaType:
+ folder.append("_premul");
+ break;
+ case kUnpremul_SkAlphaType:
+ folder.append("_unpremul");
+ break;
+ default:
+ break;
+ }
+
if (1.0f != scale) {
folder.appendf("_%.3f", scale);
}
- CodecSrc* src = new CodecSrc(path, mode, dstColorType, scale);
+ CodecSrc* src = new CodecSrc(path, mode, dstColorType, dstAlphaType, scale);
push_src("image", folder, src);
}
static void push_android_codec_src(Path path, AndroidCodecSrc::Mode mode,
- CodecSrc::DstColorType dstColorType, int sampleSize) {
+ CodecSrc::DstColorType dstColorType, SkAlphaType dstAlphaType, int sampleSize) {
SkString folder;
switch (mode) {
case AndroidCodecSrc::kFullImage_Mode:
@@ -290,11 +304,22 @@ static void push_android_codec_src(Path path, AndroidCodecSrc::Mode mode,
break;
}
+ switch (dstAlphaType) {
+ case kOpaque_SkAlphaType:
+ folder.append("_opaque");
+ break;
+ case kPremul_SkAlphaType:
+ folder.append("_premul");
+ break;
+ default:
+ break;
+ }
+
if (1 != sampleSize) {
folder.appendf("_%.3f", 1.0f / (float) sampleSize);
}
- AndroidCodecSrc* src = new AndroidCodecSrc(path, mode, dstColorType, sampleSize);
+ AndroidCodecSrc* src = new AndroidCodecSrc(path, mode, dstColorType, dstAlphaType, sampleSize);
push_src("image", folder, src);
}
@@ -344,6 +369,13 @@ static void push_codec_srcs(Path path) {
break;
}
+ SkTArray<SkAlphaType> alphaModes;
+ alphaModes.push_back(kPremul_SkAlphaType);
+ // FIXME: Currently we cannot draw unpremultiplied sources. skbug.com/3338 and skbug.com/3339
+ // alphaModes.push_back(kUnpremul_SkAlphaType);
+ if (codec->getInfo().alphaType() == kOpaque_SkAlphaType) {
+ alphaModes.push_back(kOpaque_SkAlphaType);
+ }
for (CodecSrc::Mode mode : nativeModes) {
// SkCodecImageGenerator only runs for the default colorType
@@ -353,14 +385,17 @@ static void push_codec_srcs(Path path) {
if (CodecSrc::kGen_Mode == mode) {
// FIXME: The gpu backend does not draw kGray sources correctly. (skbug.com/4822)
if (kGray_8_SkColorType != codec->getInfo().colorType()) {
- push_codec_src(path, mode, CodecSrc::kGetFromCanvas_DstColorType, 1.0f);
+ push_codec_src(path, mode, CodecSrc::kGetFromCanvas_DstColorType,
+ codec->getInfo().alphaType(), 1.0f);
}
continue;
}
for (float scale : nativeScales) {
for (uint32_t i = 0; i < numColorTypes; i++) {
- push_codec_src(path, mode, colorTypes[i], scale);
+ for (SkAlphaType alphaType : alphaModes) {
+ push_codec_src(path, mode, colorTypes[i], alphaType, scale);
+ }
}
}
}
@@ -384,11 +419,13 @@ static void push_codec_srcs(Path path) {
for (int sampleSize : sampleSizes) {
for (uint32_t i = 0; i < numColorTypes; i++) {
- push_android_codec_src(path, AndroidCodecSrc::kFullImage_Mode, colorTypes[i],
- sampleSize);
- if (subset) {
- push_android_codec_src(path, AndroidCodecSrc::kDivisor_Mode, colorTypes[i],
- sampleSize);
+ for (SkAlphaType alphaType : alphaModes) {
+ push_android_codec_src(path, AndroidCodecSrc::kFullImage_Mode, colorTypes[i],
+ alphaType, sampleSize);
+ if (subset) {
+ push_android_codec_src(path, AndroidCodecSrc::kDivisor_Mode, colorTypes[i],
+ alphaType, sampleSize);
+ }
}
}
}
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 29886807a7..9712fd73a0 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -233,10 +233,12 @@ Name BRDSrc::name() const {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType, float scale)
+CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType, SkAlphaType dstAlphaType,
+ float scale)
: fPath(path)
, fMode(mode)
, fDstColorType(dstColorType)
+ , fDstAlphaType(dstAlphaType)
, fScale(scale)
{}
@@ -251,30 +253,26 @@ bool CodecSrc::veto(SinkFlags flags) const {
return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDirect;
}
-bool get_decode_info(SkImageInfo* decodeInfo, const SkImageInfo& defaultInfo,
- SkColorType canvasColorType, CodecSrc::DstColorType dstColorType) {
+bool get_decode_info(SkImageInfo* decodeInfo, SkColorType canvasColorType,
+ CodecSrc::DstColorType dstColorType) {
switch (dstColorType) {
case CodecSrc::kIndex8_Always_DstColorType:
if (kRGB_565_SkColorType == canvasColorType) {
return false;
}
- *decodeInfo = defaultInfo.makeColorType(kIndex_8_SkColorType);
+ *decodeInfo = decodeInfo->makeColorType(kIndex_8_SkColorType);
break;
case CodecSrc::kGrayscale_Always_DstColorType:
if (kRGB_565_SkColorType == canvasColorType) {
return false;
}
- *decodeInfo = defaultInfo.makeColorType(kGray_8_SkColorType);
+ *decodeInfo = decodeInfo->makeColorType(kGray_8_SkColorType);
break;
default:
- *decodeInfo = defaultInfo.makeColorType(canvasColorType);
+ *decodeInfo = decodeInfo->makeColorType(canvasColorType);
break;
}
- // FIXME: Currently we cannot draw unpremultiplied sources.
- if (decodeInfo->alphaType() == kUnpremul_SkAlphaType) {
- *decodeInfo = decodeInfo->makeAlphaType(kPremul_SkAlphaType);
- }
return true;
}
@@ -319,9 +317,8 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
return SkStringPrintf("Couldn't create codec for %s.", fPath.c_str());
}
- SkImageInfo decodeInfo;
- if (!get_decode_info(&decodeInfo, codec->getInfo(), canvas->imageInfo().colorType(),
- fDstColorType)) {
+ SkImageInfo decodeInfo = codec->getInfo().makeAlphaType(fDstAlphaType);
+ if (!get_decode_info(&decodeInfo, canvas->imageInfo().colorType(), fDstColorType)) {
return Error::Nonfatal("Testing non-565 to 565 is uninteresting.");
}
@@ -570,10 +567,11 @@ Name CodecSrc::name() const {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
AndroidCodecSrc::AndroidCodecSrc(Path path, Mode mode, CodecSrc::DstColorType dstColorType,
- int sampleSize)
+ SkAlphaType dstAlphaType, int sampleSize)
: fPath(path)
, fMode(mode)
, fDstColorType(dstColorType)
+ , fDstAlphaType(dstAlphaType)
, fSampleSize(sampleSize)
{}
@@ -593,9 +591,8 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const {
return SkStringPrintf("Couldn't create android codec for %s.", fPath.c_str());
}
- SkImageInfo decodeInfo;
- if (!get_decode_info(&decodeInfo, codec->getInfo(), canvas->imageInfo().colorType(),
- fDstColorType)) {
+ SkImageInfo decodeInfo = codec->getInfo().makeAlphaType(fDstAlphaType);
+ if (!get_decode_info(&decodeInfo, canvas->imageInfo().colorType(), fDstColorType)) {
return Error::Nonfatal("Testing non-565 to 565 is uninteresting.");
}
diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h
index d02eeaf101..a719bd154a 100644
--- a/dm/DMSrcSink.h
+++ b/dm/DMSrcSink.h
@@ -118,7 +118,7 @@ public:
kIndex8_Always_DstColorType,
kGrayscale_Always_DstColorType,
};
- CodecSrc(Path, Mode, DstColorType, float);
+ CodecSrc(Path, Mode, DstColorType, SkAlphaType, float);
Error draw(SkCanvas*) const override;
SkISize size() const override;
@@ -128,6 +128,7 @@ private:
Path fPath;
Mode fMode;
DstColorType fDstColorType;
+ SkAlphaType fDstAlphaType;
float fScale;
};
@@ -140,7 +141,7 @@ public:
kDivisor_Mode,
};
- AndroidCodecSrc(Path, Mode, CodecSrc::DstColorType, int sampleSize);
+ AndroidCodecSrc(Path, Mode, CodecSrc::DstColorType, SkAlphaType, int sampleSize);
Error draw(SkCanvas*) const override;
SkISize size() const override;
@@ -150,6 +151,7 @@ private:
Path fPath;
Mode fMode;
CodecSrc::DstColorType fDstColorType;
+ SkAlphaType fDstAlphaType;
int fSampleSize;
};